aboutsummaryrefslogtreecommitdiff
path: root/contrib/wpa_supplicant/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/wpa_supplicant/common.c')
-rw-r--r--contrib/wpa_supplicant/common.c479
1 files changed, 347 insertions, 132 deletions
diff --git a/contrib/wpa_supplicant/common.c b/contrib/wpa_supplicant/common.c
index 4b756d8f9292..c8d6f130a960 100644
--- a/contrib/wpa_supplicant/common.c
+++ b/contrib/wpa_supplicant/common.c
@@ -1,6 +1,6 @@
/*
* wpa_supplicant/hostapd / common helper functions, etc.
- * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -12,70 +12,20 @@
* See README and COPYING for more details.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <time.h>
-#include <sys/time.h>
-#ifdef CONFIG_NATIVE_WINDOWS
-#include <winsock2.h>
-#include <wincrypt.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
+#include "includes.h"
#include "common.h"
+#ifdef CONFIG_DEBUG_FILE
+static FILE *out_file = NULL;
+#endif /* CONFIG_DEBUG_FILE */
+int wpa_debug_use_file = 0;
int wpa_debug_level = MSG_INFO;
int wpa_debug_show_keys = 0;
int wpa_debug_timestamp = 0;
-int hostapd_get_rand(u8 *buf, size_t len)
-{
-#ifdef CONFIG_NATIVE_WINDOWS
- HCRYPTPROV prov;
- BOOL ret;
-
- if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- return -1;
-
- ret = CryptGenRandom(prov, len, buf);
- CryptReleaseContext(prov, 0);
-
- return ret ? 0 : -1;
-#else /* CONFIG_NATIVE_WINDOWS */
- FILE *f;
- size_t rc;
-
- f = fopen("/dev/urandom", "r");
- if (f == NULL) {
- printf("Could not open /dev/urandom.\n");
- return -1;
- }
-
- rc = fread(buf, 1, len, f);
- fclose(f);
-
- return rc != len ? -1 : 0;
-#endif /* CONFIG_NATIVE_WINDOWS */
-}
-
-
-void hostapd_hexdump(const char *title, const u8 *buf, size_t len)
-{
- size_t i;
- printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
- for (i = 0; i < len; i++)
- printf(" %02x", buf[i]);
- printf("\n");
-}
-
-
static int hex2num(char c)
{
if (c >= '0' && c <= '9')
@@ -139,7 +89,8 @@ int hwaddr_aton(const char *txt, u8 *addr)
*/
int hexstr2bin(const char *hex, u8 *buf, size_t len)
{
- int i, a;
+ size_t i;
+ int a;
const char *ipos = hex;
u8 *opos = buf;
@@ -154,45 +105,6 @@ int hexstr2bin(const char *hex, u8 *buf, size_t len)
}
-char * rel2abs_path(const char *rel_path)
-{
- char *buf = NULL, *cwd, *ret;
- size_t len = 128, cwd_len, rel_len, ret_len;
-
- if (rel_path[0] == '/')
- return strdup(rel_path);
-
- for (;;) {
- buf = malloc(len);
- if (buf == NULL)
- return NULL;
- cwd = getcwd(buf, len);
- if (cwd == NULL) {
- free(buf);
- if (errno != ERANGE) {
- return NULL;
- }
- len *= 2;
- } else {
- break;
- }
- }
-
- cwd_len = strlen(cwd);
- rel_len = strlen(rel_path);
- ret_len = cwd_len + 1 + rel_len + 1;
- ret = malloc(ret_len);
- if (ret) {
- memcpy(ret, cwd, cwd_len);
- ret[cwd_len] = '/';
- memcpy(ret + cwd_len + 1, rel_path, rel_len);
- ret[ret_len - 1] = '\0';
- }
- free(buf);
- return ret;
-}
-
-
/**
* inc_byte_array - Increment arbitrary length byte array by one
* @counter: Pointer to byte array
@@ -214,40 +126,40 @@ void inc_byte_array(u8 *counter, size_t len)
}
-void print_char(char c)
+void wpa_get_ntp_timestamp(u8 *buf)
{
- if (c >= 32 && c < 127)
- printf("%c", c);
- else
- printf("<%02x>", c);
+ struct os_time now;
+ u32 sec, usec;
+
+ /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
+ os_get_time(&now);
+ sec = host_to_be32(now.sec + 2208988800U); /* Epoch to 1900 */
+ /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
+ usec = now.usec;
+ usec = host_to_be32(4295 * usec - (usec >> 5) - (usec >> 9));
+ os_memcpy(buf, (u8 *) &sec, 4);
+ os_memcpy(buf + 4, (u8 *) &usec, 4);
}
-void fprint_char(FILE *f, char c)
-{
- if (c >= 32 && c < 127)
- fprintf(f, "%c", c);
- else
- fprintf(f, "<%02x>", c);
-}
-
#ifndef CONFIG_NO_STDOUT_DEBUG
void wpa_debug_print_timestamp(void)
{
- struct timeval tv;
- char buf[16];
+ struct os_time tv;
if (!wpa_debug_timestamp)
return;
- gettimeofday(&tv, NULL);
- if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S",
- localtime((const time_t *) &tv.tv_sec)) <= 0) {
- snprintf(buf, sizeof(buf), "%u", (int) tv.tv_sec);
- }
- printf("%s.%06u: ", buf, (unsigned int) tv.tv_usec);
+ os_get_time(&tv);
+#ifdef CONFIG_DEBUG_FILE
+ if (out_file) {
+ fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
+ (unsigned int) tv.usec);
+ } else
+#endif /* CONFIG_DEBUG_FILE */
+ printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
}
@@ -269,8 +181,17 @@ void wpa_printf(int level, char *fmt, ...)
va_start(ap, fmt);
if (level >= wpa_debug_level) {
wpa_debug_print_timestamp();
+#ifdef CONFIG_DEBUG_FILE
+ if (out_file) {
+ vfprintf(out_file, fmt, ap);
+ fprintf(out_file, "\n");
+ } else {
+#endif /* CONFIG_DEBUG_FILE */
vprintf(fmt, ap);
printf("\n");
+#ifdef CONFIG_DEBUG_FILE
+ }
+#endif /* CONFIG_DEBUG_FILE */
}
va_end(ap);
}
@@ -283,6 +204,21 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf,
if (level < wpa_debug_level)
return;
wpa_debug_print_timestamp();
+#ifdef CONFIG_DEBUG_FILE
+ if (out_file) {
+ fprintf(out_file, "%s - hexdump(len=%lu):",
+ title, (unsigned long) len);
+ if (buf == NULL) {
+ fprintf(out_file, " [NULL]");
+ } else if (show) {
+ for (i = 0; i < len; i++)
+ fprintf(out_file, " %02x", buf[i]);
+ } else {
+ fprintf(out_file, " [REMOVED]");
+ }
+ fprintf(out_file, "\n");
+ } else {
+#endif /* CONFIG_DEBUG_FILE */
printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
if (buf == NULL) {
printf(" [NULL]");
@@ -293,6 +229,9 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf,
printf(" [REMOVED]");
}
printf("\n");
+#ifdef CONFIG_DEBUG_FILE
+ }
+#endif /* CONFIG_DEBUG_FILE */
}
void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
@@ -310,13 +249,51 @@ void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
size_t len, int show)
{
- int i, llen;
+ size_t i, llen;
const u8 *pos = buf;
- const int line_len = 16;
+ const size_t line_len = 16;
if (level < wpa_debug_level)
return;
wpa_debug_print_timestamp();
+#ifdef CONFIG_DEBUG_FILE
+ if (out_file) {
+ if (!show) {
+ fprintf(out_file,
+ "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
+ title, (unsigned long) len);
+ return;
+ }
+ if (buf == NULL) {
+ fprintf(out_file,
+ "%s - hexdump_ascii(len=%lu): [NULL]\n",
+ title, (unsigned long) len);
+ return;
+ }
+ fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
+ title, (unsigned long) len);
+ while (len) {
+ llen = len > line_len ? line_len : len;
+ fprintf(out_file, " ");
+ for (i = 0; i < llen; i++)
+ fprintf(out_file, " %02x", pos[i]);
+ for (i = llen; i < line_len; i++)
+ fprintf(out_file, " ");
+ fprintf(out_file, " ");
+ for (i = 0; i < llen; i++) {
+ if (isprint(pos[i]))
+ fprintf(out_file, "%c", pos[i]);
+ else
+ fprintf(out_file, "_");
+ }
+ for (i = llen; i < line_len; i++)
+ fprintf(out_file, " ");
+ fprintf(out_file, "\n");
+ pos += llen;
+ len -= llen;
+ }
+ } else {
+#endif /* CONFIG_DEBUG_FILE */
if (!show) {
printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
title, (unsigned long) len);
@@ -348,6 +325,9 @@ static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
pos += llen;
len -= llen;
}
+#ifdef CONFIG_DEBUG_FILE
+ }
+#endif /* CONFIG_DEBUG_FILE */
}
@@ -363,26 +343,261 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
}
+
+int wpa_debug_open_file(void)
+{
+#ifdef CONFIG_DEBUG_FILE
+ static int count = 0;
+ char fname[64];
+ if (!wpa_debug_use_file)
+ return 0;
+#ifdef _WIN32
+ os_snprintf(fname, sizeof(fname), "\\Temp\\wpa_supplicant-log-%d.txt",
+ count++);
+#else /* _WIN32 */
+ os_snprintf(fname, sizeof(fname), "/tmp/wpa_supplicant-log-%d.txt",
+ count++);
+#endif /* _WIN32 */
+ out_file = fopen(fname, "w");
+ return out_file == NULL ? -1 : 0;
+#else /* CONFIG_DEBUG_FILE */
+ return 0;
+#endif /* CONFIG_DEBUG_FILE */
+}
+
+
+void wpa_debug_close_file(void)
+{
+#ifdef CONFIG_DEBUG_FILE
+ if (!wpa_debug_use_file)
+ return;
+ fclose(out_file);
+ out_file = NULL;
+#endif /* CONFIG_DEBUG_FILE */
+}
+
#endif /* CONFIG_NO_STDOUT_DEBUG */
-#ifdef CONFIG_NATIVE_WINDOWS
+#ifndef CONFIG_NO_WPA_MSG
+static wpa_msg_cb_func wpa_msg_cb = NULL;
+
+void wpa_msg_register_cb(wpa_msg_cb_func func)
+{
+ wpa_msg_cb = func;
+}
+
+
+void wpa_msg(void *ctx, int level, char *fmt, ...)
+{
+ va_list ap;
+ char *buf;
+ const int buflen = 2048;
+ int len;
-#define EPOCHFILETIME (116444736000000000ULL)
+ buf = os_malloc(buflen);
+ if (buf == NULL) {
+ wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
+ "buffer");
+ return;
+ }
+ va_start(ap, fmt);
+ len = vsnprintf(buf, buflen, fmt, ap);
+ va_end(ap);
+ wpa_printf(level, "%s", buf);
+ if (wpa_msg_cb)
+ wpa_msg_cb(ctx, level, buf, len);
+ os_free(buf);
+}
+#endif /* CONFIG_NO_WPA_MSG */
-int gettimeofday(struct timeval *tv, struct timezone *tz)
+
+static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
+ size_t len, int uppercase)
{
- FILETIME ft;
- LARGE_INTEGER li;
- ULONGLONG t;
+ size_t i;
+ char *pos = buf, *end = buf + buf_size;
+ int ret;
+ if (buf_size == 0)
+ return 0;
+ for (i = 0; i < len; i++) {
+ ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
+ data[i]);
+ if (ret < 0 || ret >= end - pos) {
+ end[-1] = '\0';
+ return pos - buf;
+ }
+ pos += ret;
+ }
+ end[-1] = '\0';
+ return pos - buf;
+}
- GetSystemTimeAsFileTime(&ft);
- li.LowPart = ft.dwLowDateTime;
- li.HighPart = ft.dwHighDateTime;
- t = (li.QuadPart - EPOCHFILETIME) / 10;
- tv->tv_sec = (long) (t / 1000000);
- tv->tv_usec = (long) (t % 1000000);
+/**
+ * wpa_snprintf_hex - Print data as a hex string into a buffer
+ * @buf: Memory area to use as the output buffer
+ * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
+ * @data: Data to be printed
+ * @len: Length of data in bytes
+ * Returns: Number of bytes written
+ */
+int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
+{
+ return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
+}
- return 0;
+
+/**
+ * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
+ * @buf: Memory area to use as the output buffer
+ * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
+ * @data: Data to be printed
+ * @len: Length of data in bytes
+ * Returns: Number of bytes written
+ */
+int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
+ size_t len)
+{
+ return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
+}
+
+
+#ifdef CONFIG_ANSI_C_EXTRA
+
+#ifdef _WIN32_WCE
+void perror(const char *s)
+{
+ wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
+ s, (int) GetLastError());
+}
+#endif /* _WIN32_WCE */
+
+
+int optind = 1;
+int optopt;
+char *optarg;
+
+int getopt(int argc, char *const argv[], const char *optstring)
+{
+ static int optchr = 1;
+ char *cp;
+
+ if (optchr == 1) {
+ if (optind >= argc) {
+ /* all arguments processed */
+ return EOF;
+ }
+
+ if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
+ /* no option characters */
+ return EOF;
+ }
+ }
+
+ if (os_strcmp(argv[optind], "--") == 0) {
+ /* no more options */
+ optind++;
+ return EOF;
+ }
+
+ optopt = argv[optind][optchr];
+ cp = os_strchr(optstring, optopt);
+ if (cp == NULL || optopt == ':') {
+ if (argv[optind][++optchr] == '\0') {
+ optchr = 1;
+ optind++;
+ }
+ return '?';
+ }
+
+ if (cp[1] == ':') {
+ /* Argument required */
+ optchr = 1;
+ if (argv[optind][optchr + 1]) {
+ /* No space between option and argument */
+ optarg = &argv[optind++][optchr + 1];
+ } else if (++optind >= argc) {
+ /* option requires an argument */
+ return '?';
+ } else {
+ /* Argument in the next argv */
+ optarg = argv[optind++];
+ }
+ } else {
+ /* No argument */
+ if (argv[optind][++optchr] == '\0') {
+ optchr = 1;
+ optind++;
+ }
+ optarg = NULL;
+ }
+ return *cp;
+}
+#endif /* CONFIG_ANSI_C_EXTRA */
+
+
+#ifdef CONFIG_NATIVE_WINDOWS
+/**
+ * wpa_unicode2ascii_inplace - Convert unicode string into ASCII
+ * @str: Pointer to string to convert
+ *
+ * This function converts a unicode string to ASCII using the same
+ * buffer for output. If UNICODE is not set, the buffer is not
+ * modified.
+ */
+void wpa_unicode2ascii_inplace(TCHAR *str)
+{
+#ifdef UNICODE
+ char *dst = (char *) str;
+ while (*str)
+ *dst++ = (char) *str++;
+ *dst = '\0';
+#endif /* UNICODE */
+}
+
+
+TCHAR * wpa_strdup_tchar(const char *str)
+{
+#ifdef UNICODE
+ TCHAR *buf;
+ buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
+ if (buf == NULL)
+ return NULL;
+ wsprintf(buf, L"%S", str);
+ return buf;
+#else /* UNICODE */
+ return os_strdup(str);
+#endif /* UNICODE */
}
#endif /* CONFIG_NATIVE_WINDOWS */
+
+
+/**
+ * wpa_ssid_txt - Convert SSID to a printable string
+ * @ssid: SSID (32-octet string)
+ * @ssid_len: Length of ssid in octets
+ * Returns: Pointer to a printable string
+ *
+ * This function can be used to convert SSIDs into printable form. In most
+ * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
+ * does not limit the used character set, so anything could be used in an SSID.
+ *
+ * This function uses a static buffer, so only one call can be used at the
+ * time, i.e., this is not re-entrant and the returned buffer must be used
+ * before calling this again.
+ */
+const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len)
+{
+ static char ssid_txt[33];
+ char *pos;
+
+ if (ssid_len > 32)
+ ssid_len = 32;
+ os_memcpy(ssid_txt, ssid, ssid_len);
+ ssid_txt[ssid_len] = '\0';
+ for (pos = ssid_txt; *pos != '\0'; pos++) {
+ if ((u8) *pos < 32 || (u8) *pos >= 127)
+ *pos = '_';
+ }
+ return ssid_txt;
+}