diff options
Diffstat (limited to 'contrib/wpa/src/utils')
-rw-r--r-- | contrib/wpa/src/utils/.gitignore | 1 | ||||
-rw-r--r-- | contrib/wpa/src/utils/base64.c | 2 | ||||
-rw-r--r-- | contrib/wpa/src/utils/common.c | 6 | ||||
-rw-r--r-- | contrib/wpa/src/utils/common.h | 24 | ||||
-rw-r--r-- | contrib/wpa/src/utils/eloop_none.c | 410 | ||||
-rw-r--r-- | contrib/wpa/src/utils/eloop_win.c | 622 | ||||
-rw-r--r-- | contrib/wpa/src/utils/os_none.c | 226 | ||||
-rw-r--r-- | contrib/wpa/src/utils/os_unix.c | 3 | ||||
-rw-r--r-- | contrib/wpa/src/utils/os_win32.c | 222 | ||||
-rw-r--r-- | contrib/wpa/src/utils/wpa_debug.c | 28 | ||||
-rw-r--r-- | contrib/wpa/src/utils/wpa_debug.h | 20 | ||||
-rw-r--r-- | contrib/wpa/src/utils/wpabuf.c | 4 |
12 files changed, 1560 insertions, 8 deletions
diff --git a/contrib/wpa/src/utils/.gitignore b/contrib/wpa/src/utils/.gitignore deleted file mode 100644 index a438335..0000000 --- a/contrib/wpa/src/utils/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.d diff --git a/contrib/wpa/src/utils/base64.c b/contrib/wpa/src/utils/base64.c index 0eadb81..13fc511 100644 --- a/contrib/wpa/src/utils/base64.c +++ b/contrib/wpa/src/utils/base64.c @@ -43,6 +43,8 @@ unsigned char * base64_encode(const unsigned char *src, size_t len, olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ olen += olen / 72; /* line feeds */ olen++; /* nul termination */ + if (olen < len) + return NULL; /* integer overflow */ out = os_malloc(olen); if (out == NULL) return NULL; diff --git a/contrib/wpa/src/utils/common.c b/contrib/wpa/src/utils/common.c index cb373c3..9a46ebe 100644 --- a/contrib/wpa/src/utils/common.c +++ b/contrib/wpa/src/utils/common.c @@ -325,3 +325,9 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) } return ssid_txt; } + + +void * __hide_aliasing_typecast(void *foo) +{ + return foo; +} diff --git a/contrib/wpa/src/utils/common.h b/contrib/wpa/src/utils/common.h index d0a2eb3..d649391 100644 --- a/contrib/wpa/src/utils/common.h +++ b/contrib/wpa/src/utils/common.h @@ -22,17 +22,24 @@ #include <byteswap.h> #endif /* __linux__ */ -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ + defined(__OpenBSD__) #include <sys/types.h> #include <sys/endian.h> #define __BYTE_ORDER _BYTE_ORDER #define __LITTLE_ENDIAN _LITTLE_ENDIAN #define __BIG_ENDIAN _BIG_ENDIAN +#ifdef __OpenBSD__ +#define bswap_16 swap16 +#define bswap_32 swap32 +#define bswap_64 swap64 +#else /* __OpenBSD__ */ #define bswap_16 bswap16 #define bswap_32 bswap32 #define bswap_64 bswap64 +#endif /* __OpenBSD__ */ #endif /* defined(__FreeBSD__) || defined(__NetBSD__) || - * defined(__DragonFly__) */ + * defined(__DragonFly__) || defined(__OpenBSD__) */ #ifdef __APPLE__ #include <sys/types.h> @@ -435,4 +442,17 @@ static inline int is_zero_ether_addr(const u8 *a) #include "wpa_debug.h" + +/* + * gcc 4.4 ends up generating strict-aliasing warnings about some very common + * networking socket uses that do not really result in a real problem and + * cannot be easily avoided with union-based type-punning due to struct + * definitions including another struct in system header files. To avoid having + * to fully disable strict-aliasing warnings, provide a mechanism to hide the + * typecast from aliasing for now. A cleaner solution will hopefully be found + * in the future to handle these cases. + */ +void * __hide_aliasing_typecast(void *foo); +#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a)) + #endif /* COMMON_H */ diff --git a/contrib/wpa/src/utils/eloop_none.c b/contrib/wpa/src/utils/eloop_none.c new file mode 100644 index 0000000..215030b --- /dev/null +++ b/contrib/wpa/src/utils/eloop_none.c @@ -0,0 +1,410 @@ +/* + * Event loop - empty template (basic structure, but no OS specific operations) + * Copyright (c) 2002-2005, 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 + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "eloop.h" + + +struct eloop_sock { + int sock; + void *eloop_data; + void *user_data; + void (*handler)(int sock, void *eloop_ctx, void *sock_ctx); +}; + +struct eloop_timeout { + struct os_time time; + void *eloop_data; + void *user_data; + void (*handler)(void *eloop_ctx, void *sock_ctx); + struct eloop_timeout *next; +}; + +struct eloop_signal { + int sig; + void *user_data; + void (*handler)(int sig, void *eloop_ctx, void *signal_ctx); + int signaled; +}; + +struct eloop_data { + void *user_data; + + int max_sock, reader_count; + struct eloop_sock *readers; + + struct eloop_timeout *timeout; + + int signal_count; + struct eloop_signal *signals; + int signaled; + int pending_terminate; + + int terminate; + int reader_table_changed; +}; + +static struct eloop_data eloop; + + +int eloop_init(void *user_data) +{ + memset(&eloop, 0, sizeof(eloop)); + eloop.user_data = user_data; + return 0; +} + + +int eloop_register_read_sock(int sock, + void (*handler)(int sock, void *eloop_ctx, + void *sock_ctx), + void *eloop_data, void *user_data) +{ + struct eloop_sock *tmp; + + tmp = (struct eloop_sock *) + realloc(eloop.readers, + (eloop.reader_count + 1) * sizeof(struct eloop_sock)); + if (tmp == NULL) + return -1; + + tmp[eloop.reader_count].sock = sock; + tmp[eloop.reader_count].eloop_data = eloop_data; + tmp[eloop.reader_count].user_data = user_data; + tmp[eloop.reader_count].handler = handler; + eloop.reader_count++; + eloop.readers = tmp; + if (sock > eloop.max_sock) + eloop.max_sock = sock; + eloop.reader_table_changed = 1; + + return 0; +} + + +void eloop_unregister_read_sock(int sock) +{ + int i; + + if (eloop.readers == NULL || eloop.reader_count == 0) + return; + + for (i = 0; i < eloop.reader_count; i++) { + if (eloop.readers[i].sock == sock) + break; + } + if (i == eloop.reader_count) + return; + if (i != eloop.reader_count - 1) { + memmove(&eloop.readers[i], &eloop.readers[i + 1], + (eloop.reader_count - i - 1) * + sizeof(struct eloop_sock)); + } + eloop.reader_count--; + eloop.reader_table_changed = 1; +} + + +int eloop_register_timeout(unsigned int secs, unsigned int usecs, + void (*handler)(void *eloop_ctx, void *timeout_ctx), + void *eloop_data, void *user_data) +{ + struct eloop_timeout *timeout, *tmp, *prev; + + timeout = (struct eloop_timeout *) malloc(sizeof(*timeout)); + if (timeout == NULL) + return -1; + os_get_time(&timeout->time); + timeout->time.sec += secs; + timeout->time.usec += usecs; + while (timeout->time.usec >= 1000000) { + timeout->time.sec++; + timeout->time.usec -= 1000000; + } + timeout->eloop_data = eloop_data; + timeout->user_data = user_data; + timeout->handler = handler; + timeout->next = NULL; + + if (eloop.timeout == NULL) { + eloop.timeout = timeout; + return 0; + } + + prev = NULL; + tmp = eloop.timeout; + while (tmp != NULL) { + if (os_time_before(&timeout->time, &tmp->time)) + break; + prev = tmp; + tmp = tmp->next; + } + + if (prev == NULL) { + timeout->next = eloop.timeout; + eloop.timeout = timeout; + } else { + timeout->next = prev->next; + prev->next = timeout; + } + + return 0; +} + + +int eloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx), + void *eloop_data, void *user_data) +{ + struct eloop_timeout *timeout, *prev, *next; + int removed = 0; + + prev = NULL; + timeout = eloop.timeout; + while (timeout != NULL) { + next = timeout->next; + + if (timeout->handler == handler && + (timeout->eloop_data == eloop_data || + eloop_data == ELOOP_ALL_CTX) && + (timeout->user_data == user_data || + user_data == ELOOP_ALL_CTX)) { + if (prev == NULL) + eloop.timeout = next; + else + prev->next = next; + free(timeout); + removed++; + } else + prev = timeout; + + timeout = next; + } + + return removed; +} + + +int eloop_is_timeout_registered(void (*handler)(void *eloop_ctx, + void *timeout_ctx), + void *eloop_data, void *user_data) +{ + struct eloop_timeout *tmp; + + tmp = eloop.timeout; + while (tmp != NULL) { + if (tmp->handler == handler && + tmp->eloop_data == eloop_data && + tmp->user_data == user_data) + return 1; + + tmp = tmp->next; + } + + return 0; +} + + +/* TODO: replace with suitable signal handler */ +#if 0 +static void eloop_handle_signal(int sig) +{ + int i; + + eloop.signaled++; + for (i = 0; i < eloop.signal_count; i++) { + if (eloop.signals[i].sig == sig) { + eloop.signals[i].signaled++; + break; + } + } +} +#endif + + +static void eloop_process_pending_signals(void) +{ + int i; + + if (eloop.signaled == 0) + return; + eloop.signaled = 0; + + if (eloop.pending_terminate) { + eloop.pending_terminate = 0; + } + + for (i = 0; i < eloop.signal_count; i++) { + if (eloop.signals[i].signaled) { + eloop.signals[i].signaled = 0; + eloop.signals[i].handler(eloop.signals[i].sig, + eloop.user_data, + eloop.signals[i].user_data); + } + } +} + + +int eloop_register_signal(int sig, + void (*handler)(int sig, void *eloop_ctx, + void *signal_ctx), + void *user_data) +{ + struct eloop_signal *tmp; + + tmp = (struct eloop_signal *) + realloc(eloop.signals, + (eloop.signal_count + 1) * + sizeof(struct eloop_signal)); + if (tmp == NULL) + return -1; + + tmp[eloop.signal_count].sig = sig; + tmp[eloop.signal_count].user_data = user_data; + tmp[eloop.signal_count].handler = handler; + tmp[eloop.signal_count].signaled = 0; + eloop.signal_count++; + eloop.signals = tmp; + + /* TODO: register signal handler */ + + return 0; +} + + +int eloop_register_signal_terminate(void (*handler)(int sig, void *eloop_ctx, + void *signal_ctx), + void *user_data) +{ +#if 0 + /* TODO: for example */ + int ret = eloop_register_signal(SIGINT, handler, user_data); + if (ret == 0) + ret = eloop_register_signal(SIGTERM, handler, user_data); + return ret; +#endif + return 0; +} + + +int eloop_register_signal_reconfig(void (*handler)(int sig, void *eloop_ctx, + void *signal_ctx), + void *user_data) +{ +#if 0 + /* TODO: for example */ + return eloop_register_signal(SIGHUP, handler, user_data); +#endif + return 0; +} + + +void eloop_run(void) +{ + int i; + struct os_time tv, now; + + while (!eloop.terminate && + (eloop.timeout || eloop.reader_count > 0)) { + if (eloop.timeout) { + os_get_time(&now); + if (os_time_before(&now, &eloop.timeout->time)) + os_time_sub(&eloop.timeout->time, &now, &tv); + else + tv.sec = tv.usec = 0; + } + + /* + * TODO: wait for any event (read socket ready, timeout (tv), + * signal + */ + os_sleep(1, 0); /* just a dummy wait for testing */ + + eloop_process_pending_signals(); + + /* check if some registered timeouts have occurred */ + if (eloop.timeout) { + struct eloop_timeout *tmp; + + os_get_time(&now); + if (!os_time_before(&now, &eloop.timeout->time)) { + tmp = eloop.timeout; + eloop.timeout = eloop.timeout->next; + tmp->handler(tmp->eloop_data, + tmp->user_data); + free(tmp); + } + + } + + eloop.reader_table_changed = 0; + for (i = 0; i < eloop.reader_count; i++) { + /* + * TODO: call each handler that has pending data to + * read + */ + if (0 /* TODO: eloop.readers[i].sock ready */) { + eloop.readers[i].handler( + eloop.readers[i].sock, + eloop.readers[i].eloop_data, + eloop.readers[i].user_data); + if (eloop.reader_table_changed) + break; + } + } + } +} + + +void eloop_terminate(void) +{ + eloop.terminate = 1; +} + + +void eloop_destroy(void) +{ + struct eloop_timeout *timeout, *prev; + + timeout = eloop.timeout; + while (timeout != NULL) { + prev = timeout; + timeout = timeout->next; + free(prev); + } + free(eloop.readers); + free(eloop.signals); +} + + +int eloop_terminated(void) +{ + return eloop.terminate; +} + + +void eloop_wait_for_read_sock(int sock) +{ + /* + * TODO: wait for the file descriptor to have something available for + * reading + */ +} + + +void * eloop_get_user_data(void) +{ + return eloop.user_data; +} diff --git a/contrib/wpa/src/utils/eloop_win.c b/contrib/wpa/src/utils/eloop_win.c new file mode 100644 index 0000000..c95aa76 --- /dev/null +++ b/contrib/wpa/src/utils/eloop_win.c @@ -0,0 +1,622 @@ +/* + * Event loop based on Windows events and WaitForMultipleObjects + * 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 + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" +#include <winsock2.h> + +#include "common.h" +#include "eloop.h" + + +struct eloop_sock { + int sock; + void *eloop_data; + void *user_data; + eloop_sock_handler handler; + WSAEVENT event; +}; + +struct eloop_event { + void *eloop_data; + void *user_data; + eloop_event_handler handler; + HANDLE event; +}; + +struct eloop_timeout { + struct os_time time; + void *eloop_data; + void *user_data; + eloop_timeout_handler handler; + struct eloop_timeout *next; +}; + +struct eloop_signal { + int sig; + void *user_data; + eloop_signal_handler handler; + int signaled; +}; + +struct eloop_data { + void *user_data; + + int max_sock; + size_t reader_count; + struct eloop_sock *readers; + + size_t event_count; + struct eloop_event *events; + + struct eloop_timeout *timeout; + + int signal_count; + struct eloop_signal *signals; + int signaled; + int pending_terminate; + + int terminate; + int reader_table_changed; + + struct eloop_signal term_signal; + HANDLE term_event; + + HANDLE *handles; + size_t num_handles; +}; + +static struct eloop_data eloop; + + +int eloop_init(void *user_data) +{ + os_memset(&eloop, 0, sizeof(eloop)); + eloop.user_data = user_data; + eloop.num_handles = 1; + eloop.handles = os_malloc(eloop.num_handles * + sizeof(eloop.handles[0])); + if (eloop.handles == NULL) + return -1; + + eloop.term_event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (eloop.term_event == NULL) { + printf("CreateEvent() failed: %d\n", + (int) GetLastError()); + os_free(eloop.handles); + return -1; + } + + return 0; +} + + +static int eloop_prepare_handles(void) +{ + HANDLE *n; + + if (eloop.num_handles > eloop.reader_count + eloop.event_count + 8) + return 0; + n = os_realloc(eloop.handles, + eloop.num_handles * 2 * sizeof(eloop.handles[0])); + if (n == NULL) + return -1; + eloop.handles = n; + eloop.num_handles *= 2; + return 0; +} + + +int eloop_register_read_sock(int sock, eloop_sock_handler handler, + void *eloop_data, void *user_data) +{ + WSAEVENT event; + struct eloop_sock *tmp; + + if (eloop_prepare_handles()) + return -1; + + event = WSACreateEvent(); + if (event == WSA_INVALID_EVENT) { + printf("WSACreateEvent() failed: %d\n", WSAGetLastError()); + return -1; + } + + if (WSAEventSelect(sock, event, FD_READ)) { + printf("WSAEventSelect() failed: %d\n", WSAGetLastError()); + WSACloseEvent(event); + return -1; + } + tmp = os_realloc(eloop.readers, + (eloop.reader_count + 1) * sizeof(struct eloop_sock)); + if (tmp == NULL) { + WSAEventSelect(sock, event, 0); + WSACloseEvent(event); + return -1; + } + + tmp[eloop.reader_count].sock = sock; + tmp[eloop.reader_count].eloop_data = eloop_data; + tmp[eloop.reader_count].user_data = user_data; + tmp[eloop.reader_count].handler = handler; + tmp[eloop.reader_count].event = event; + eloop.reader_count++; + eloop.readers = tmp; + if (sock > eloop.max_sock) + eloop.max_sock = sock; + eloop.reader_table_changed = 1; + + return 0; +} + + +void eloop_unregister_read_sock(int sock) +{ + size_t i; + + if (eloop.readers == NULL || eloop.reader_count == 0) + return; + + for (i = 0; i < eloop.reader_count; i++) { + if (eloop.readers[i].sock == sock) + break; + } + if (i == eloop.reader_count) + return; + + WSAEventSelect(eloop.readers[i].sock, eloop.readers[i].event, 0); + WSACloseEvent(eloop.readers[i].event); + + if (i != eloop.reader_count - 1) { + os_memmove(&eloop.readers[i], &eloop.readers[i + 1], + (eloop.reader_count - i - 1) * + sizeof(struct eloop_sock)); + } + eloop.reader_count--; + eloop.reader_table_changed = 1; +} + + +int eloop_register_event(void *event, size_t event_size, + eloop_event_handler handler, + void *eloop_data, void *user_data) +{ + struct eloop_event *tmp; + HANDLE h = event; + + if (event_size != sizeof(HANDLE) || h == INVALID_HANDLE_VALUE) + return -1; + + if (eloop_prepare_handles()) + return -1; + + tmp = os_realloc(eloop.events, + (eloop.event_count + 1) * sizeof(struct eloop_event)); + if (tmp == NULL) + return -1; + + tmp[eloop.event_count].eloop_data = eloop_data; + tmp[eloop.event_count].user_data = user_data; + tmp[eloop.event_count].handler = handler; + tmp[eloop.event_count].event = h; + eloop.event_count++; + eloop.events = tmp; + + return 0; +} + + +void eloop_unregister_event(void *event, size_t event_size) +{ + size_t i; + HANDLE h = event; + + if (eloop.events == NULL || eloop.event_count == 0 || + event_size != sizeof(HANDLE)) + return; + + for (i = 0; i < eloop.event_count; i++) { + if (eloop.events[i].event == h) + break; + } + if (i == eloop.event_count) + return; + + if (i != eloop.event_count - 1) { + os_memmove(&eloop.events[i], &eloop.events[i + 1], + (eloop.event_count - i - 1) * + sizeof(struct eloop_event)); + } + eloop.event_count--; +} + + +int eloop_register_timeout(unsigned int secs, unsigned int usecs, + eloop_timeout_handler handler, + void *eloop_data, void *user_data) +{ + struct eloop_timeout *timeout, *tmp, *prev; + + timeout = os_malloc(sizeof(*timeout)); + if (timeout == NULL) + return -1; + os_get_time(&timeout->time); + timeout->time.sec += secs; + timeout->time.usec += usecs; + while (timeout->time.usec >= 1000000) { + timeout->time.sec++; + timeout->time.usec -= 1000000; + } + timeout->eloop_data = eloop_data; + timeout->user_data = user_data; + timeout->handler = handler; + timeout->next = NULL; + + if (eloop.timeout == NULL) { + eloop.timeout = timeout; + return 0; + } + + prev = NULL; + tmp = eloop.timeout; + while (tmp != NULL) { + if (os_time_before(&timeout->time, &tmp->time)) + break; + prev = tmp; + tmp = tmp->next; + } + + if (prev == NULL) { + timeout->next = eloop.timeout; + eloop.timeout = timeout; + } else { + timeout->next = prev->next; + prev->next = timeout; + } + + return 0; +} + + +int eloop_cancel_timeout(eloop_timeout_handler handler, + void *eloop_data, void *user_data) +{ + struct eloop_timeout *timeout, *prev, *next; + int removed = 0; + + prev = NULL; + timeout = eloop.timeout; + while (timeout != NULL) { + next = timeout->next; + + if (timeout->handler == handler && + (timeout->eloop_data == eloop_data || + eloop_data == ELOOP_ALL_CTX) && + (timeout->user_data == user_data || + user_data == ELOOP_ALL_CTX)) { + if (prev == NULL) + eloop.timeout = next; + else + prev->next = next; + os_free(timeout); + removed++; + } else + prev = timeout; + + timeout = next; + } + + return removed; +} + + +int eloop_is_timeout_registered(eloop_timeout_handler handler, + void *eloop_data, void *user_data) +{ + struct eloop_timeout *tmp; + + tmp = eloop.timeout; + while (tmp != NULL) { + if (tmp->handler == handler && + tmp->eloop_data == eloop_data && + tmp->user_data == user_data) + return 1; + + tmp = tmp->next; + } + + return 0; +} + + +/* TODO: replace with suitable signal handler */ +#if 0 +static void eloop_handle_signal(int sig) +{ + int i; + + eloop.signaled++; + for (i = 0; i < eloop.signal_count; i++) { + if (eloop.signals[i].sig == sig) { + eloop.signals[i].signaled++; + break; + } + } +} +#endif + + +static void eloop_process_pending_signals(void) +{ + int i; + + if (eloop.signaled == 0) + return; + eloop.signaled = 0; + + if (eloop.pending_terminate) { + eloop.pending_terminate = 0; + } + + for (i = 0; i < eloop.signal_count; i++) { + if (eloop.signals[i].signaled) { + eloop.signals[i].signaled = 0; + eloop.signals[i].handler(eloop.signals[i].sig, + eloop.user_data, + eloop.signals[i].user_data); + } + } + + if (eloop.term_signal.signaled) { + eloop.term_signal.signaled = 0; + eloop.term_signal.handler(eloop.term_signal.sig, + eloop.user_data, + eloop.term_signal.user_data); + } +} + + +int eloop_register_signal(int sig, eloop_signal_handler handler, + void *user_data) +{ + struct eloop_signal *tmp; + + tmp = os_realloc(eloop.signals, + (eloop.signal_count + 1) * + sizeof(struct eloop_signal)); + if (tmp == NULL) + return -1; + + tmp[eloop.signal_count].sig = sig; + tmp[eloop.signal_count].user_data = user_data; + tmp[eloop.signal_count].handler = handler; + tmp[eloop.signal_count].signaled = 0; + eloop.signal_count++; + eloop.signals = tmp; + + /* TODO: register signal handler */ + + return 0; +} + + +#ifndef _WIN32_WCE +static BOOL eloop_handle_console_ctrl(DWORD type) +{ + switch (type) { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + eloop.signaled++; + eloop.term_signal.signaled++; + SetEvent(eloop.term_event); + return TRUE; + default: + return FALSE; + } +} +#endif /* _WIN32_WCE */ + + +int eloop_register_signal_terminate(eloop_signal_handler handler, + void *user_data) +{ +#ifndef _WIN32_WCE + if (SetConsoleCtrlHandler((PHANDLER_ROUTINE) eloop_handle_console_ctrl, + TRUE) == 0) { + printf("SetConsoleCtrlHandler() failed: %d\n", + (int) GetLastError()); + return -1; + } +#endif /* _WIN32_WCE */ + + eloop.term_signal.handler = handler; + eloop.term_signal.user_data = user_data; + + return 0; +} + + +int eloop_register_signal_reconfig(eloop_signal_handler handler, + void *user_data) +{ + /* TODO */ + return 0; +} + + +void eloop_run(void) +{ + struct os_time tv, now; + DWORD count, ret, timeout, err; + size_t i; + + while (!eloop.terminate && + (eloop.timeout || eloop.reader_count > 0 || + eloop.event_count > 0)) { + tv.sec = tv.usec = 0; + if (eloop.timeout) { + os_get_time(&now); + if (os_time_before(&now, &eloop.timeout->time)) + os_time_sub(&eloop.timeout->time, &now, &tv); + } + + count = 0; + for (i = 0; i < eloop.event_count; i++) + eloop.handles[count++] = eloop.events[i].event; + + for (i = 0; i < eloop.reader_count; i++) + eloop.handles[count++] = eloop.readers[i].event; + + if (eloop.term_event) + eloop.handles[count++] = eloop.term_event; + + if (eloop.timeout) + timeout = tv.sec * 1000 + tv.usec / 1000; + else + timeout = INFINITE; + + if (count > MAXIMUM_WAIT_OBJECTS) { + printf("WaitForMultipleObjects: Too many events: " + "%d > %d (ignoring extra events)\n", + (int) count, MAXIMUM_WAIT_OBJECTS); + count = MAXIMUM_WAIT_OBJECTS; + } +#ifdef _WIN32_WCE + ret = WaitForMultipleObjects(count, eloop.handles, FALSE, + timeout); +#else /* _WIN32_WCE */ + ret = WaitForMultipleObjectsEx(count, eloop.handles, FALSE, + timeout, TRUE); +#endif /* _WIN32_WCE */ + err = GetLastError(); + + eloop_process_pending_signals(); + + /* check if some registered timeouts have occurred */ + if (eloop.timeout) { + struct eloop_timeout *tmp; + + os_get_time(&now); + if (!os_time_before(&now, &eloop.timeout->time)) { + tmp = eloop.timeout; + eloop.timeout = eloop.timeout->next; + tmp->handler(tmp->eloop_data, + tmp->user_data); + os_free(tmp); + } + + } + + if (ret == WAIT_FAILED) { + printf("WaitForMultipleObjects(count=%d) failed: %d\n", + (int) count, (int) err); + os_sleep(1, 0); + continue; + } + +#ifndef _WIN32_WCE + if (ret == WAIT_IO_COMPLETION) + continue; +#endif /* _WIN32_WCE */ + + if (ret == WAIT_TIMEOUT) + continue; + + while (ret >= WAIT_OBJECT_0 && + ret < WAIT_OBJECT_0 + eloop.event_count) { + eloop.events[ret].handler( + eloop.events[ret].eloop_data, + eloop.events[ret].user_data); + ret = WaitForMultipleObjects(eloop.event_count, + eloop.handles, FALSE, 0); + } + + eloop.reader_table_changed = 0; + for (i = 0; i < eloop.reader_count; i++) { + WSANETWORKEVENTS events; + if (WSAEnumNetworkEvents(eloop.readers[i].sock, + eloop.readers[i].event, + &events) == 0 && + (events.lNetworkEvents & FD_READ)) { + eloop.readers[i].handler( + eloop.readers[i].sock, + eloop.readers[i].eloop_data, + eloop.readers[i].user_data); + if (eloop.reader_table_changed) + break; + } + } + } +} + + +void eloop_terminate(void) +{ + eloop.terminate = 1; + SetEvent(eloop.term_event); +} + + +void eloop_destroy(void) +{ + struct eloop_timeout *timeout, *prev; + + timeout = eloop.timeout; + while (timeout != NULL) { + prev = timeout; + timeout = timeout->next; + os_free(prev); + } + os_free(eloop.readers); + os_free(eloop.signals); + if (eloop.term_event) + CloseHandle(eloop.term_event); + os_free(eloop.handles); + eloop.handles = NULL; + os_free(eloop.events); + eloop.events = NULL; +} + + +int eloop_terminated(void) +{ + return eloop.terminate; +} + + +void eloop_wait_for_read_sock(int sock) +{ + WSAEVENT event; + + event = WSACreateEvent(); + if (event == WSA_INVALID_EVENT) { + printf("WSACreateEvent() failed: %d\n", WSAGetLastError()); + return; + } + + if (WSAEventSelect(sock, event, FD_READ)) { + printf("WSAEventSelect() failed: %d\n", WSAGetLastError()); + WSACloseEvent(event); + return ; + } + + WaitForSingleObject(event, INFINITE); + WSAEventSelect(sock, event, 0); + WSACloseEvent(event); +} + + +void * eloop_get_user_data(void) +{ + return eloop.user_data; +} diff --git a/contrib/wpa/src/utils/os_none.c b/contrib/wpa/src/utils/os_none.c new file mode 100644 index 0000000..bab8f17 --- /dev/null +++ b/contrib/wpa/src/utils/os_none.c @@ -0,0 +1,226 @@ +/* + * wpa_supplicant/hostapd / Empty OS specific functions + * Copyright (c) 2005-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 + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * This file can be used as a starting point when adding a new OS target. The + * functions here do not really work as-is since they are just empty or only + * return an error value. os_internal.c can be used as another starting point + * or reference since it has example implementation of many of these functions. + */ + +#include "includes.h" + +#include "os.h" + +void os_sleep(os_time_t sec, os_time_t usec) +{ +} + + +int os_get_time(struct os_time *t) +{ + return -1; +} + + +int os_mktime(int year, int month, int day, int hour, int min, int sec, + os_time_t *t) +{ + return -1; +} + + +int os_daemonize(const char *pid_file) +{ + return -1; +} + + +void os_daemonize_terminate(const char *pid_file) +{ +} + + +int os_get_random(unsigned char *buf, size_t len) +{ + return -1; +} + + +unsigned long os_random(void) +{ + return 0; +} + + +char * os_rel2abs_path(const char *rel_path) +{ + return NULL; /* strdup(rel_path) can be used here */ +} + + +int os_program_init(void) +{ + return 0; +} + + +void os_program_deinit(void) +{ +} + + +int os_setenv(const char *name, const char *value, int overwrite) +{ + return -1; +} + + +int os_unsetenv(const char *name) +{ + return -1; +} + + +char * os_readfile(const char *name, size_t *len) +{ + return NULL; +} + + +void * os_zalloc(size_t size) +{ + return NULL; +} + + +#ifdef OS_NO_C_LIB_DEFINES +void * os_malloc(size_t size) +{ + return NULL; +} + + +void * os_realloc(void *ptr, size_t size) +{ + return NULL; +} + + +void os_free(void *ptr) +{ +} + + +void * os_memcpy(void *dest, const void *src, size_t n) +{ + return dest; +} + + +void * os_memmove(void *dest, const void *src, size_t n) +{ + return dest; +} + + +void * os_memset(void *s, int c, size_t n) +{ + return s; +} + + +int os_memcmp(const void *s1, const void *s2, size_t n) +{ + return 0; +} + + +char * os_strdup(const char *s) +{ + return NULL; +} + + +size_t os_strlen(const char *s) +{ + return 0; +} + + +int os_strcasecmp(const char *s1, const char *s2) +{ + /* + * Ignoring case is not required for main functionality, so just use + * the case sensitive version of the function. + */ + return os_strcmp(s1, s2); +} + + +int os_strncasecmp(const char *s1, const char *s2, size_t n) +{ + /* + * Ignoring case is not required for main functionality, so just use + * the case sensitive version of the function. + */ + return os_strncmp(s1, s2, n); +} + + +char * os_strchr(const char *s, int c) +{ + return NULL; +} + + +char * os_strrchr(const char *s, int c) +{ + return NULL; +} + + +int os_strcmp(const char *s1, const char *s2) +{ + return 0; +} + + +int os_strncmp(const char *s1, const char *s2, size_t n) +{ + return 0; +} + + +char * os_strncpy(char *dest, const char *src, size_t n) +{ + return dest; +} + + +size_t os_strlcpy(char *dest, const char *src, size_t size) +{ + return 0; +} + + +char * os_strstr(const char *haystack, const char *needle) +{ + return NULL; +} + + +int os_snprintf(char *str, size_t size, const char *format, ...) +{ + return 0; +} +#endif /* OS_NO_C_LIB_DEFINES */ diff --git a/contrib/wpa/src/utils/os_unix.c b/contrib/wpa/src/utils/os_unix.c index 060892d..bc2fc40 100644 --- a/contrib/wpa/src/utils/os_unix.c +++ b/contrib/wpa/src/utils/os_unix.c @@ -227,7 +227,8 @@ int os_setenv(const char *name, const char *value, int overwrite) int os_unsetenv(const char *name) { -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \ + defined(__OpenBSD__) unsetenv(name); return 0; #else diff --git a/contrib/wpa/src/utils/os_win32.c b/contrib/wpa/src/utils/os_win32.c new file mode 100644 index 0000000..0740964 --- /dev/null +++ b/contrib/wpa/src/utils/os_win32.c @@ -0,0 +1,222 @@ +/* + * wpa_supplicant/hostapd / OS specific functions for Win32 systems + * Copyright (c) 2005-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 + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" +#include <winsock2.h> +#include <wincrypt.h> + +#include "os.h" + +void os_sleep(os_time_t sec, os_time_t usec) +{ + if (sec) + Sleep(sec * 1000); + if (usec) + Sleep(usec / 1000); +} + + +int os_get_time(struct os_time *t) +{ +#define EPOCHFILETIME (116444736000000000ULL) + FILETIME ft; + LARGE_INTEGER li; + ULONGLONG tt; + +#ifdef _WIN32_WCE + SYSTEMTIME st; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); +#else /* _WIN32_WCE */ + GetSystemTimeAsFileTime(&ft); +#endif /* _WIN32_WCE */ + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + tt = (li.QuadPart - EPOCHFILETIME) / 10; + t->sec = (os_time_t) (tt / 1000000); + t->usec = (os_time_t) (tt % 1000000); + + return 0; +} + + +int os_mktime(int year, int month, int day, int hour, int min, int sec, + os_time_t *t) +{ + struct tm tm, *tm1; + time_t t_local, t1, t2; + os_time_t tz_offset; + + if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || + hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || + sec > 60) + return -1; + + memset(&tm, 0, sizeof(tm)); + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = min; + tm.tm_sec = sec; + + t_local = mktime(&tm); + + /* figure out offset to UTC */ + tm1 = localtime(&t_local); + if (tm1) { + t1 = mktime(tm1); + tm1 = gmtime(&t_local); + if (tm1) { + t2 = mktime(tm1); + tz_offset = t2 - t1; + } else + tz_offset = 0; + } else + tz_offset = 0; + + *t = (os_time_t) t_local - tz_offset; + return 0; +} + + +int os_daemonize(const char *pid_file) +{ + /* TODO */ + return -1; +} + + +void os_daemonize_terminate(const char *pid_file) +{ +} + + +int os_get_random(unsigned char *buf, size_t len) +{ + 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; +} + + +unsigned long os_random(void) +{ + return rand(); +} + + +char * os_rel2abs_path(const char *rel_path) +{ + return _strdup(rel_path); +} + + +int os_program_init(void) +{ +#ifdef CONFIG_NATIVE_WINDOWS + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 0), &wsaData)) { + printf("Could not find a usable WinSock.dll\n"); + return -1; + } +#endif /* CONFIG_NATIVE_WINDOWS */ + return 0; +} + + +void os_program_deinit(void) +{ +#ifdef CONFIG_NATIVE_WINDOWS + WSACleanup(); +#endif /* CONFIG_NATIVE_WINDOWS */ +} + + +int os_setenv(const char *name, const char *value, int overwrite) +{ + return -1; +} + + +int os_unsetenv(const char *name) +{ + return -1; +} + + +char * os_readfile(const char *name, size_t *len) +{ + FILE *f; + char *buf; + + f = fopen(name, "rb"); + if (f == NULL) + return NULL; + + fseek(f, 0, SEEK_END); + *len = ftell(f); + fseek(f, 0, SEEK_SET); + + buf = malloc(*len); + if (buf == NULL) { + fclose(f); + return NULL; + } + + fread(buf, 1, *len, f); + fclose(f); + + return buf; +} + + +void * os_zalloc(size_t size) +{ + return calloc(1, size); +} + + +size_t os_strlcpy(char *dest, const char *src, size_t siz) +{ + const char *s = src; + size_t left = siz; + + if (left) { + /* Copy string up to the maximum size of the dest buffer */ + while (--left != 0) { + if ((*dest++ = *s++) == '\0') + break; + } + } + + if (left == 0) { + /* Not enough room for the string; force NUL-termination */ + if (siz != 0) + *dest = '\0'; + while (*s++) + ; /* determine total src string length */ + } + + return s - src - 1; +} diff --git a/contrib/wpa/src/utils/wpa_debug.c b/contrib/wpa/src/utils/wpa_debug.c index 5d53bf8..0f46aee 100644 --- a/contrib/wpa/src/utils/wpa_debug.c +++ b/contrib/wpa/src/utils/wpa_debug.c @@ -95,7 +95,7 @@ static int syslog_priority(int level) * * Note: New line '\n' is added to the end of the text when printing to stdout. */ -void wpa_printf(int level, char *fmt, ...) +void wpa_printf(int level, const char *fmt, ...) { va_list ap; @@ -314,7 +314,7 @@ void wpa_msg_register_cb(wpa_msg_cb_func func) } -void wpa_msg(void *ctx, int level, char *fmt, ...) +void wpa_msg(void *ctx, int level, const char *fmt, ...) { va_list ap; char *buf; @@ -335,6 +335,30 @@ void wpa_msg(void *ctx, int level, char *fmt, ...) wpa_msg_cb(ctx, level, buf, len); os_free(buf); } + + +void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) +{ + va_list ap; + char *buf; + const int buflen = 2048; + int len; + + if (!wpa_msg_cb) + return; + + buf = os_malloc(buflen); + if (buf == NULL) { + wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate " + "message buffer"); + return; + } + va_start(ap, fmt); + len = vsnprintf(buf, buflen, fmt, ap); + va_end(ap); + wpa_msg_cb(ctx, level, buf, len); + os_free(buf); +} #endif /* CONFIG_NO_WPA_MSG */ diff --git a/contrib/wpa/src/utils/wpa_debug.h b/contrib/wpa/src/utils/wpa_debug.h index 2d23f06..b4010d5 100644 --- a/contrib/wpa/src/utils/wpa_debug.h +++ b/contrib/wpa/src/utils/wpa_debug.h @@ -60,7 +60,7 @@ void wpa_debug_print_timestamp(void); * * Note: New line '\n' is added to the end of the text when printing to stdout. */ -void wpa_printf(int level, char *fmt, ...) +void wpa_printf(int level, const char *fmt, ...) PRINTF_FORMAT(2, 3); /** @@ -141,6 +141,7 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, #ifdef CONFIG_NO_WPA_MSG #define wpa_msg(args...) do { } while (0) +#define wpa_msg_ctrl(args...) do { } while (0) #define wpa_msg_register_cb(f) do { } while (0) #else /* CONFIG_NO_WPA_MSG */ /** @@ -157,7 +158,22 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, * * Note: New line '\n' is added to the end of the text when printing to stdout. */ -void wpa_msg(void *ctx, int level, char *fmt, ...) PRINTF_FORMAT(3, 4); +void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); + +/** + * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. + * This function is like wpa_msg(), but it sends the output only to the + * attached ctrl_iface monitors. In other words, it can be used for frequent + * events that do not need to be sent to syslog. + */ +void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) +PRINTF_FORMAT(3, 4); typedef void (*wpa_msg_cb_func)(void *ctx, int level, const char *txt, size_t len); diff --git a/contrib/wpa/src/utils/wpabuf.c b/contrib/wpa/src/utils/wpabuf.c index c544179..8181912 100644 --- a/contrib/wpa/src/utils/wpabuf.c +++ b/contrib/wpa/src/utils/wpabuf.c @@ -29,6 +29,10 @@ static void wpabuf_overflow(const struct wpabuf *buf, size_t len) int wpabuf_resize(struct wpabuf **_buf, size_t add_len) { struct wpabuf *buf = *_buf; + if (buf == NULL) { + *_buf = wpabuf_alloc(add_len); + return *_buf == NULL ? -1 : 0; + } if (buf->used + add_len > buf->size) { unsigned char *nbuf; if (buf->ext_data) { |