diff options
Diffstat (limited to 'contrib/wpa/src/utils')
26 files changed, 1612 insertions, 270 deletions
diff --git a/contrib/wpa/src/utils/.gitignore b/contrib/wpa/src/utils/.gitignore new file mode 100644 index 0000000..833734f --- /dev/null +++ b/contrib/wpa/src/utils/.gitignore @@ -0,0 +1 @@ +libutils.a diff --git a/contrib/wpa/src/utils/Makefile b/contrib/wpa/src/utils/Makefile index cffba62..527cf3e 100644 --- a/contrib/wpa/src/utils/Makefile +++ b/contrib/wpa/src/utils/Makefile @@ -1,9 +1,36 @@ -all: - @echo Nothing to be made. +all: libutils.a clean: - for d in $(SUBDIRS); do make -C $$d clean; done - rm -f *~ *.o *.d + rm -f *~ *.o *.d libutils.a install: @echo Nothing to be made. + + +include ../lib.rules + +#CFLAGS += -DWPA_TRACE +CFLAGS += -DCONFIG_IPV6 + +LIB_OBJS= \ + base64.o \ + common.o \ + ip_addr.o \ + radiotap.o \ + trace.o \ + uuid.o \ + wpa_debug.o \ + wpabuf.o + +# Pick correct OS wrapper implementation +LIB_OBJS += os_unix.o + +# Pick correct event loop implementation +LIB_OBJS += eloop.o + +#LIB_OBJS += pcsc_funcs.o + +libutils.a: $(LIB_OBJS) + $(AR) crT $@ $? + +-include $(OBJS:%.o=%.d) diff --git a/contrib/wpa/src/utils/base64.c b/contrib/wpa/src/utils/base64.c index 13fc511..155bfce 100644 --- a/contrib/wpa/src/utils/base64.c +++ b/contrib/wpa/src/utils/base64.c @@ -152,38 +152,3 @@ unsigned char * base64_decode(const unsigned char *src, size_t len, *out_len = pos - out; return out; } - - -#ifdef TEST_MAIN - -int main(int argc, char *argv[]) -{ - FILE *f; - size_t len, elen; - unsigned char *buf, *e; - - if (argc != 4) { - printf("Usage: base64 <encode|decode> <in file> <out file>\n"); - return -1; - } - - buf = os_readfile(argv[2], &len); - if (buf == NULL) - return -1; - - if (strcmp(argv[1], "encode") == 0) - e = base64_encode(buf, len, &elen); - else - e = base64_decode(buf, len, &elen); - if (e == NULL) - return -2; - f = fopen(argv[3], "w"); - if (f == NULL) - return -3; - fwrite(e, 1, elen, f); - fclose(f); - free(e); - - return 0; -} -#endif /* TEST_MAIN */ diff --git a/contrib/wpa/src/utils/build_config.h b/contrib/wpa/src/utils/build_config.h index 1e147fe..3666778 100644 --- a/contrib/wpa/src/utils/build_config.h +++ b/contrib/wpa/src/utils/build_config.h @@ -28,7 +28,6 @@ #define CONFIG_ANSI_C_EXTRA #define CONFIG_WINPCAP #define IEEE8021X_EAPOL -#define EAP_TLS_FUNCS #define PKCS12_FUNCS #define PCSC_FUNCS #define CONFIG_CTRL_IFACE @@ -48,16 +47,8 @@ #define _CRT_SECURE_NO_DEPRECATE #ifdef USE_INTERNAL_CRYPTO -#define CONFIG_TLS_INTERNAL #define CONFIG_TLS_INTERNAL_CLIENT #define CONFIG_INTERNAL_LIBTOMMATH -#define INTERNAL_AES -#define INTERNAL_SHA1 -#define INTERNAL_SHA256 -#define INTERNAL_MD5 -#define INTERNAL_MD4 -#define INTERNAL_DES -#define CONFIG_INTERNAL_X509 #define CONFIG_CRYPTO_INTERNAL #endif /* USE_INTERNAL_CRYPTO */ #endif /* CONFIG_WIN32_DEFAULTS */ @@ -69,15 +60,7 @@ #define CONFIG_NO_HOSTAPD_LOGGER #define CONFIG_NO_STDOUT_DEBUG #define CONFIG_BACKEND_FILE -#define INTERNAL_AES -#define INTERNAL_SHA1 -#define INTERNAL_MD5 -#define INTERNAL_MD4 -#define INTERNAL_DES #define CONFIG_INTERNAL_LIBTOMMATH -#define CONFIG_INTERNAL_X509 -#define EAP_TLS_FUNCS -#define CONFIG_TLS_INTERNAL #define CONFIG_CRYPTO_INTERNAL #define IEEE8021X_EAPOL #define PKCS12_FUNCS @@ -92,4 +75,31 @@ #define EAP_FAST #endif /* __SYMBIAN32__ */ +#ifdef CONFIG_XCODE_DEFAULTS +#define CONFIG_DRIVER_OSX +#define CONFIG_BACKEND_FILE +#define IEEE8021X_EAPOL +#define PKCS12_FUNCS +#define CONFIG_CTRL_IFACE +#define CONFIG_CTRL_IFACE_UNIX +#define CONFIG_DEBUG_FILE +#define EAP_MD5 +#define EAP_TLS +#define EAP_MSCHAPv2 +#define EAP_PEAP +#define EAP_TTLS +#define EAP_GTC +#define EAP_OTP +#define EAP_LEAP +#define EAP_TNC +#define CONFIG_WPS +#define EAP_WSC + +#ifdef USE_INTERNAL_CRYPTO +#define CONFIG_TLS_INTERNAL_CLIENT +#define CONFIG_INTERNAL_LIBTOMMATH +#define CONFIG_CRYPTO_INTERNAL +#endif /* USE_INTERNAL_CRYPTO */ +#endif /* CONFIG_XCODE_DEFAULTS */ + #endif /* BUILD_CONFIG_H */ diff --git a/contrib/wpa/src/utils/common.c b/contrib/wpa/src/utils/common.c index 9a46ebe..1b8ea80 100644 --- a/contrib/wpa/src/utils/common.c +++ b/contrib/wpa/src/utils/common.c @@ -43,7 +43,7 @@ static int hex2byte(const char *hex) /** - * hwaddr_aton - Convert ASCII string to MAC address + * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format) * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) @@ -71,6 +71,36 @@ int hwaddr_aton(const char *txt, u8 *addr) /** + * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format) + * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455) + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: Characters used (> 0) on success, -1 on failure + */ +int hwaddr_aton2(const char *txt, u8 *addr) +{ + int i; + const char *pos = txt; + + for (i = 0; i < 6; i++) { + int a, b; + + while (*pos == ':' || *pos == '.' || *pos == '-') + pos++; + + a = hex2num(*pos++); + if (a < 0) + return -1; + b = hex2num(*pos++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + } + + return pos - txt; +} + + +/** * hexstr2bin - Convert ASCII hex string into binary data * @hex: ASCII hex string (e.g., "01ab") * @buf: Buffer for the binary data diff --git a/contrib/wpa/src/utils/common.h b/contrib/wpa/src/utils/common.h index d649391..f17bf69 100644 --- a/contrib/wpa/src/utils/common.h +++ b/contrib/wpa/src/utils/common.h @@ -17,7 +17,7 @@ #include "os.h" -#ifdef __linux__ +#if defined(__linux__) || defined(__GLIBC__) #include <endian.h> #include <byteswap.h> #endif /* __linux__ */ @@ -314,6 +314,24 @@ static inline unsigned int wpa_swap_32(unsigned int v) #ifndef ETH_ALEN #define ETH_ALEN 6 #endif +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif +#ifndef ETH_P_ALL +#define ETH_P_ALL 0x0003 +#endif +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ +#ifndef ETH_P_EAPOL +#define ETH_P_EAPOL ETH_P_PAE +#endif /* ETH_P_EAPOL */ +#ifndef ETH_P_RSN_PREAUTH +#define ETH_P_RSN_PREAUTH 0x88c7 +#endif /* ETH_P_RSN_PREAUTH */ +#ifndef ETH_P_RRB +#define ETH_P_RRB 0x890D +#endif /* ETH_P_RRB */ #ifdef __GNUC__ @@ -418,6 +436,7 @@ typedef u64 __bitwise le64; #endif /* __must_check */ int hwaddr_aton(const char *txt, u8 *addr); +int hwaddr_aton2(const char *txt, u8 *addr); int hexstr2bin(const char *hex, u8 *buf, size_t len); void inc_byte_array(u8 *counter, size_t len); void wpa_get_ntp_timestamp(u8 *buf); diff --git a/contrib/wpa/src/utils/eloop.c b/contrib/wpa/src/utils/eloop.c index 4edb2a7..4b61598 100644 --- a/contrib/wpa/src/utils/eloop.c +++ b/contrib/wpa/src/utils/eloop.c @@ -1,6 +1,6 @@ /* * Event loop based on select() loop - * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi> + * Copyright (c) 2002-2009, 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 @@ -15,6 +15,8 @@ #include "includes.h" #include "common.h" +#include "trace.h" +#include "list.h" #include "eloop.h" @@ -23,14 +25,20 @@ struct eloop_sock { void *eloop_data; void *user_data; eloop_sock_handler handler; + WPA_TRACE_REF(eloop); + WPA_TRACE_REF(user); + WPA_TRACE_INFO }; struct eloop_timeout { + struct dl_list list; struct os_time time; void *eloop_data; void *user_data; eloop_timeout_handler handler; - struct eloop_timeout *next; + WPA_TRACE_REF(eloop); + WPA_TRACE_REF(user); + WPA_TRACE_INFO }; struct eloop_signal { @@ -47,15 +55,13 @@ struct eloop_sock_table { }; struct eloop_data { - void *user_data; - int max_sock; struct eloop_sock_table readers; struct eloop_sock_table writers; struct eloop_sock_table exceptions; - struct eloop_timeout *timeout; + struct dl_list timeout; int signal_count; struct eloop_signal *signals; @@ -69,10 +75,56 @@ struct eloop_data { static struct eloop_data eloop; -int eloop_init(void *user_data) +#ifdef WPA_TRACE + +static void eloop_sigsegv_handler(int sig) +{ + wpa_trace_show("eloop SIGSEGV"); + abort(); +} + +static void eloop_trace_sock_add_ref(struct eloop_sock_table *table) +{ + int i; + if (table == NULL || table->table == NULL) + return; + for (i = 0; i < table->count; i++) { + wpa_trace_add_ref(&table->table[i], eloop, + table->table[i].eloop_data); + wpa_trace_add_ref(&table->table[i], user, + table->table[i].user_data); + } +} + + +static void eloop_trace_sock_remove_ref(struct eloop_sock_table *table) +{ + int i; + if (table == NULL || table->table == NULL) + return; + for (i = 0; i < table->count; i++) { + wpa_trace_remove_ref(&table->table[i], eloop, + table->table[i].eloop_data); + wpa_trace_remove_ref(&table->table[i], user, + table->table[i].user_data); + } +} + +#else /* WPA_TRACE */ + +#define eloop_trace_sock_add_ref(table) do { } while (0) +#define eloop_trace_sock_remove_ref(table) do { } while (0) + +#endif /* WPA_TRACE */ + + +int eloop_init(void) { os_memset(&eloop, 0, sizeof(eloop)); - eloop.user_data = user_data; + dl_list_init(&eloop.timeout); +#ifdef WPA_TRACE + signal(SIGSEGV, eloop_sigsegv_handler); +#endif /* WPA_TRACE */ return 0; } @@ -86,6 +138,7 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table, if (table == NULL) return -1; + eloop_trace_sock_remove_ref(table); tmp = (struct eloop_sock *) os_realloc(table->table, (table->count + 1) * sizeof(struct eloop_sock)); @@ -96,11 +149,13 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table, tmp[table->count].eloop_data = eloop_data; tmp[table->count].user_data = user_data; tmp[table->count].handler = handler; + wpa_trace_record(&tmp[table->count]); table->count++; table->table = tmp; if (sock > eloop.max_sock) eloop.max_sock = sock; table->changed = 1; + eloop_trace_sock_add_ref(table); return 0; } @@ -120,6 +175,7 @@ static void eloop_sock_table_remove_sock(struct eloop_sock_table *table, } if (i == table->count) return; + eloop_trace_sock_remove_ref(table); if (i != table->count - 1) { os_memmove(&table->table[i], &table->table[i + 1], (table->count - i - 1) * @@ -127,6 +183,7 @@ static void eloop_sock_table_remove_sock(struct eloop_sock_table *table, } table->count--; table->changed = 1; + eloop_trace_sock_add_ref(table); } @@ -171,12 +228,17 @@ static void eloop_sock_table_destroy(struct eloop_sock_table *table) if (table) { int i; for (i = 0; i < table->count && table->table; i++) { - printf("ELOOP: remaining socket: sock=%d " - "eloop_data=%p user_data=%p handler=%p\n", - table->table[i].sock, - table->table[i].eloop_data, - table->table[i].user_data, - table->table[i].handler); + wpa_printf(MSG_INFO, "ELOOP: remaining socket: " + "sock=%d eloop_data=%p user_data=%p " + "handler=%p", + table->table[i].sock, + table->table[i].eloop_data, + table->table[i].user_data, + table->table[i].handler); + wpa_trace_dump_funcname("eloop unregistered socket " + "handler", + table->table[i].handler); + wpa_trace_dump("eloop sock", &table->table[i]); } os_free(table->table); } @@ -237,9 +299,9 @@ 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; + struct eloop_timeout *timeout, *tmp; - timeout = os_malloc(sizeof(*timeout)); + timeout = os_zalloc(sizeof(*timeout)); if (timeout == NULL) return -1; if (os_get_time(&timeout->time) < 0) { @@ -255,60 +317,48 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs, 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; + wpa_trace_add_ref(timeout, eloop, eloop_data); + wpa_trace_add_ref(timeout, user, user_data); + wpa_trace_record(timeout); + + /* Maintain timeouts in order of increasing time */ + dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { + if (os_time_before(&timeout->time, &tmp->time)) { + dl_list_add(tmp->list.prev, &timeout->list); + return 0; + } } + dl_list_add_tail(&eloop.timeout, &timeout->list); - prev = NULL; - tmp = eloop.timeout; - while (tmp != NULL) { - if (os_time_before(&timeout->time, &tmp->time)) - break; - prev = tmp; - tmp = tmp->next; - } + return 0; +} - if (prev == NULL) { - timeout->next = eloop.timeout; - eloop.timeout = timeout; - } else { - timeout->next = prev->next; - prev->next = timeout; - } - return 0; +static void eloop_remove_timeout(struct eloop_timeout *timeout) +{ + dl_list_del(&timeout->list); + wpa_trace_remove_ref(timeout, eloop, timeout->eloop_data); + wpa_trace_remove_ref(timeout, user, timeout->user_data); + os_free(timeout); } int eloop_cancel_timeout(eloop_timeout_handler handler, void *eloop_data, void *user_data) { - struct eloop_timeout *timeout, *prev, *next; + struct eloop_timeout *timeout, *prev; int removed = 0; - prev = NULL; - timeout = eloop.timeout; - while (timeout != NULL) { - next = timeout->next; - + dl_list_for_each_safe(timeout, prev, &eloop.timeout, + struct eloop_timeout, list) { 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); + eloop_remove_timeout(timeout); removed++; - } else - prev = timeout; - - timeout = next; + } } return removed; @@ -320,14 +370,11 @@ int eloop_is_timeout_registered(eloop_timeout_handler handler, { struct eloop_timeout *tmp; - tmp = eloop.timeout; - while (tmp != NULL) { + dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { if (tmp->handler == handler && tmp->eloop_data == eloop_data && tmp->user_data == user_data) return 1; - - tmp = tmp->next; } return 0; @@ -337,11 +384,11 @@ int eloop_is_timeout_registered(eloop_timeout_handler handler, #ifndef CONFIG_NATIVE_WINDOWS static void eloop_handle_alarm(int sig) { - fprintf(stderr, "eloop: could not process SIGINT or SIGTERM in two " - "seconds. Looks like there\n" - "is a bug that ends up in a busy loop that " - "prevents clean shutdown.\n" - "Killing program forcefully.\n"); + wpa_printf(MSG_ERROR, "eloop: could not process SIGINT or SIGTERM in " + "two seconds. Looks like there\n" + "is a bug that ends up in a busy loop that " + "prevents clean shutdown.\n" + "Killing program forcefully.\n"); exit(1); } #endif /* CONFIG_NATIVE_WINDOWS */ @@ -390,7 +437,6 @@ static void eloop_process_pending_signals(void) 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); } } @@ -452,24 +498,21 @@ void eloop_run(void) rfds = os_malloc(sizeof(*rfds)); wfds = os_malloc(sizeof(*wfds)); efds = os_malloc(sizeof(*efds)); - if (rfds == NULL || wfds == NULL || efds == NULL) { - printf("eloop_run - malloc failed\n"); + if (rfds == NULL || wfds == NULL || efds == NULL) goto out; - } while (!eloop.terminate && - (eloop.timeout || eloop.readers.count > 0 || + (!dl_list_empty(&eloop.timeout) || eloop.readers.count > 0 || eloop.writers.count > 0 || eloop.exceptions.count > 0)) { - if (eloop.timeout) { + struct eloop_timeout *timeout; + timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, + list); + if (timeout) { os_get_time(&now); - if (os_time_before(&now, &eloop.timeout->time)) - os_time_sub(&eloop.timeout->time, &now, &tv); + if (os_time_before(&now, &timeout->time)) + os_time_sub(&timeout->time, &now, &tv); else tv.sec = tv.usec = 0; -#if 0 - printf("next timeout in %lu.%06lu sec\n", - tv.sec, tv.usec); -#endif _tv.tv_sec = tv.sec; _tv.tv_usec = tv.usec; } @@ -478,7 +521,7 @@ void eloop_run(void) eloop_sock_table_set_fds(&eloop.writers, wfds); eloop_sock_table_set_fds(&eloop.exceptions, efds); res = select(eloop.max_sock + 1, rfds, wfds, efds, - eloop.timeout ? &_tv : NULL); + timeout ? &_tv : NULL); if (res < 0 && errno != EINTR && errno != 0) { perror("select"); goto out; @@ -486,16 +529,17 @@ void eloop_run(void) eloop_process_pending_signals(); /* check if some registered timeouts have occurred */ - if (eloop.timeout) { - struct eloop_timeout *tmp; - + timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, + list); + if (timeout) { 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 (!os_time_before(&now, &timeout->time)) { + void *eloop_data = timeout->eloop_data; + void *user_data = timeout->user_data; + eloop_timeout_handler handler = + timeout->handler; + eloop_remove_timeout(timeout); + handler(eloop_data, user_data); } } @@ -526,24 +570,24 @@ void eloop_destroy(void) struct eloop_timeout *timeout, *prev; struct os_time now; - timeout = eloop.timeout; - if (timeout) - os_get_time(&now); - while (timeout != NULL) { + os_get_time(&now); + dl_list_for_each_safe(timeout, prev, &eloop.timeout, + struct eloop_timeout, list) { int sec, usec; - prev = timeout; - timeout = timeout->next; - sec = prev->time.sec - now.sec; - usec = prev->time.usec - now.usec; - if (prev->time.usec < now.usec) { + sec = timeout->time.sec - now.sec; + usec = timeout->time.usec - now.usec; + if (timeout->time.usec < now.usec) { sec--; usec += 1000000; } - printf("ELOOP: remaining timeout: %d.%06d eloop_data=%p " - "user_data=%p handler=%p\n", - sec, usec, prev->eloop_data, prev->user_data, - prev->handler); - os_free(prev); + wpa_printf(MSG_INFO, "ELOOP: remaining timeout: %d.%06d " + "eloop_data=%p user_data=%p handler=%p", + sec, usec, timeout->eloop_data, timeout->user_data, + timeout->handler); + wpa_trace_dump_funcname("eloop unregistered timeout handler", + timeout->handler); + wpa_trace_dump("eloop timeout", timeout); + eloop_remove_timeout(timeout); } eloop_sock_table_destroy(&eloop.readers); eloop_sock_table_destroy(&eloop.writers); @@ -569,9 +613,3 @@ void eloop_wait_for_read_sock(int sock) FD_SET(sock, &rfds); select(sock + 1, &rfds, NULL, NULL, NULL); } - - -void * eloop_get_user_data(void) -{ - return eloop.user_data; -} diff --git a/contrib/wpa/src/utils/eloop.h b/contrib/wpa/src/utils/eloop.h index cf83f38..1228f24 100644 --- a/contrib/wpa/src/utils/eloop.h +++ b/contrib/wpa/src/utils/eloop.h @@ -65,25 +65,19 @@ typedef void (*eloop_timeout_handler)(void *eloop_data, void *user_ctx); /** * eloop_signal_handler - eloop signal event callback type * @sig: Signal number - * @eloop_ctx: Registered callback context data (global user_data from - * eloop_init() call) * @signal_ctx: Registered callback context data (user_data from * eloop_register_signal(), eloop_register_signal_terminate(), or * eloop_register_signal_reconfig() call) */ -typedef void (*eloop_signal_handler)(int sig, void *eloop_ctx, - void *signal_ctx); +typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); /** * eloop_init() - Initialize global event loop data - * @user_data: Pointer to global data passed as eloop_ctx to signal handlers * Returns: 0 on success, -1 on failure * - * This function must be called before any other eloop_* function. user_data - * can be used to configure a global (to the process) pointer that will be - * passed as eloop_ctx parameter to signal handlers. + * This function must be called before any other eloop_* function. */ -int eloop_init(void *user_data); +int eloop_init(void); /** * eloop_register_read_sock - Register handler for read events @@ -231,10 +225,6 @@ int eloop_is_timeout_registered(eloop_timeout_handler handler, * handler has returned. This means that the normal limits for sighandlers * (i.e., only "safe functions" allowed) do not apply for the registered * callback. - * - * Signals are 'global' events and there is no local eloop_data pointer like - * with other handlers. The global user_data pointer registered with - * eloop_init() will be used as eloop_ctx for signal handlers. */ int eloop_register_signal(int sig, eloop_signal_handler handler, void *user_data); @@ -251,10 +241,6 @@ int eloop_register_signal(int sig, eloop_signal_handler handler, * sighandlers (i.e., only "safe functions" allowed) do not apply for the * registered callback. * - * Signals are 'global' events and there is no local eloop_data pointer like - * with other handlers. The global user_data pointer registered with - * eloop_init() will be used as eloop_ctx for signal handlers. - * * This function is a more portable version of eloop_register_signal() since * the knowledge of exact details of the signals is hidden in eloop * implementation. In case of operating systems using signal(), this function @@ -275,10 +261,6 @@ int eloop_register_signal_terminate(eloop_signal_handler handler, * limits for sighandlers (i.e., only "safe functions" allowed) do not apply * for the registered callback. * - * Signals are 'global' events and there is no local eloop_data pointer like - * with other handlers. The global user_data pointer registered with - * eloop_init() will be used as eloop_ctx for signal handlers. - * * This function is a more portable version of eloop_register_signal() since * the knowledge of exact details of the signals is hidden in eloop * implementation. In case of operating systems using signal(), this function @@ -331,10 +313,4 @@ int eloop_terminated(void); */ void eloop_wait_for_read_sock(int sock); -/** - * eloop_get_user_data - Get global user data - * Returns: user_data pointer that was registered with eloop_init() - */ -void * eloop_get_user_data(void); - #endif /* ELOOP_H */ diff --git a/contrib/wpa/src/utils/eloop_none.c b/contrib/wpa/src/utils/eloop_none.c index 215030b..18eae4e 100644 --- a/contrib/wpa/src/utils/eloop_none.c +++ b/contrib/wpa/src/utils/eloop_none.c @@ -41,8 +41,6 @@ struct eloop_signal { }; struct eloop_data { - void *user_data; - int max_sock, reader_count; struct eloop_sock *readers; @@ -60,10 +58,9 @@ struct eloop_data { static struct eloop_data eloop; -int eloop_init(void *user_data) +int eloop_init(void) { memset(&eloop, 0, sizeof(eloop)); - eloop.user_data = user_data; return 0; } @@ -402,9 +399,3 @@ void eloop_wait_for_read_sock(int sock) * 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 index c95aa76..94cc72d 100644 --- a/contrib/wpa/src/utils/eloop_win.c +++ b/contrib/wpa/src/utils/eloop_win.c @@ -50,8 +50,6 @@ struct eloop_signal { }; struct eloop_data { - void *user_data; - int max_sock; size_t reader_count; struct eloop_sock *readers; @@ -79,10 +77,9 @@ struct eloop_data { static struct eloop_data eloop; -int eloop_init(void *user_data) +int eloop_init(void) { 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])); @@ -372,7 +369,6 @@ static void eloop_process_pending_signals(void) 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); } } @@ -380,7 +376,6 @@ static void eloop_process_pending_signals(void) 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); } } @@ -614,9 +609,3 @@ void eloop_wait_for_read_sock(int sock) WSAEventSelect(sock, event, 0); WSACloseEvent(event); } - - -void * eloop_get_user_data(void) -{ - return eloop.user_data; -} diff --git a/contrib/wpa/src/utils/ip_addr.h b/contrib/wpa/src/utils/ip_addr.h index 192049a..28ccaef 100644 --- a/contrib/wpa/src/utils/ip_addr.h +++ b/contrib/wpa/src/utils/ip_addr.h @@ -16,13 +16,14 @@ #define IP_ADDR_H struct hostapd_ip_addr { + int af; /* AF_INET / AF_INET6 */ union { struct in_addr v4; #ifdef CONFIG_IPV6 struct in6_addr v6; #endif /* CONFIG_IPV6 */ + u8 max_len[16]; } u; - int af; /* AF_INET / AF_INET6 */ }; const char * hostapd_ip_txt(const struct hostapd_ip_addr *addr, char *buf, diff --git a/contrib/wpa/src/utils/list.h b/contrib/wpa/src/utils/list.h new file mode 100644 index 0000000..ed7c022 --- /dev/null +++ b/contrib/wpa/src/utils/list.h @@ -0,0 +1,89 @@ +/* + * Doubly-linked list + * Copyright (c) 2009, 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. + */ + +#ifndef LIST_H +#define LIST_H + +/** + * struct dl_list - Doubly-linked list + */ +struct dl_list { + struct dl_list *next; + struct dl_list *prev; +}; + +static inline void dl_list_init(struct dl_list *list) +{ + list->next = list; + list->prev = list; +} + +static inline void dl_list_add(struct dl_list *list, struct dl_list *item) +{ + item->next = list->next; + item->prev = list; + list->next->prev = item; + list->next = item; +} + +static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item) +{ + dl_list_add(list->prev, item); +} + +static inline void dl_list_del(struct dl_list *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; + item->next = NULL; + item->prev = NULL; +} + +static inline int dl_list_empty(struct dl_list *list) +{ + return list->next == list; +} + +static inline unsigned int dl_list_len(struct dl_list *list) +{ + struct dl_list *item; + int count = 0; + for (item = list->next; item != list; item = item->next) + count++; + return count; +} + +#ifndef offsetof +#define offsetof(type, member) ((long) &((type *) 0)->member) +#endif + +#define dl_list_entry(item, type, member) \ + ((type *) ((char *) item - offsetof(type, member))) + +#define dl_list_first(list, type, member) \ + (dl_list_empty((list)) ? NULL : \ + dl_list_entry((list)->next, type, member)) + +#define dl_list_for_each(item, list, type, member) \ + for (item = dl_list_entry((list)->next, type, member); \ + &item->member != (list); \ + item = dl_list_entry(item->member.next, type, member)) + +#define dl_list_for_each_safe(item, n, list, type, member) \ + for (item = dl_list_entry((list)->next, type, member), \ + n = dl_list_entry(item->member.next, type, member); \ + &item->member != (list); \ + item = n, n = dl_list_entry(n->member.next, type, member)) + +#endif /* LIST_H */ diff --git a/contrib/wpa/src/utils/os.h b/contrib/wpa/src/utils/os.h index d6dfea6..f4723d8 100644 --- a/contrib/wpa/src/utils/os.h +++ b/contrib/wpa/src/utils/os.h @@ -1,6 +1,6 @@ /* - * wpa_supplicant/hostapd / OS specific functions - * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi> + * OS specific functions + * Copyright (c) 2005-2009, 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 @@ -379,6 +379,12 @@ int os_snprintf(char *str, size_t size, const char *format, ...); #else /* OS_NO_C_LIB_DEFINES */ +#ifdef WPA_TRACE +void * os_malloc(size_t size); +void * os_realloc(void *ptr, size_t size); +void os_free(void *ptr); +char * os_strdup(const char *s); +#else /* WPA_TRACE */ #ifndef os_malloc #define os_malloc(s) malloc((s)) #endif @@ -388,6 +394,14 @@ int os_snprintf(char *str, size_t size, const char *format, ...); #ifndef os_free #define os_free(p) free((p)) #endif +#ifndef os_strdup +#ifdef _MSC_VER +#define os_strdup(s) _strdup(s) +#else +#define os_strdup(s) strdup(s) +#endif +#endif +#endif /* WPA_TRACE */ #ifndef os_memcpy #define os_memcpy(d, s, n) memcpy((d), (s), (n)) @@ -402,13 +416,6 @@ int os_snprintf(char *str, size_t size, const char *format, ...); #define os_memcmp(s1, s2, n) memcmp((s1), (s2), (n)) #endif -#ifndef os_strdup -#ifdef _MSC_VER -#define os_strdup(s) _strdup(s) -#else -#define os_strdup(s) strdup(s) -#endif -#endif #ifndef os_strlen #define os_strlen(s) strlen(s) #endif diff --git a/contrib/wpa/src/utils/os_internal.c b/contrib/wpa/src/utils/os_internal.c index 7b74bbf..5260e23 100644 --- a/contrib/wpa/src/utils/os_internal.c +++ b/contrib/wpa/src/utils/os_internal.c @@ -206,7 +206,12 @@ char * os_readfile(const char *name, size_t *len) return NULL; } - fread(buf, 1, *len, f); + if (fread(buf, 1, *len, f) != *len) { + fclose(f); + os_free(buf); + return NULL; + } + fclose(f); return buf; diff --git a/contrib/wpa/src/utils/os_unix.c b/contrib/wpa/src/utils/os_unix.c index bc2fc40..6f58fa4 100644 --- a/contrib/wpa/src/utils/os_unix.c +++ b/contrib/wpa/src/utils/os_unix.c @@ -1,6 +1,6 @@ /* - * wpa_supplicant/hostapd / OS specific functions for UNIX/POSIX systems - * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi> + * OS specific functions for UNIX/POSIX systems + * Copyright (c) 2005-2009, 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 @@ -16,6 +16,28 @@ #include "os.h" +#ifdef WPA_TRACE + +#include "common.h" +#include "list.h" +#include "wpa_debug.h" +#include "trace.h" + +static struct dl_list alloc_list; + +#define ALLOC_MAGIC 0xa84ef1b2 +#define FREED_MAGIC 0x67fd487a + +struct os_alloc_trace { + unsigned int magic; + struct dl_list list; + size_t len; + WPA_TRACE_INFO +}; + +#endif /* WPA_TRACE */ + + void os_sleep(os_time_t sec, os_time_t usec) { if (sec) @@ -172,16 +194,16 @@ char * os_rel2abs_path(const char *rel_path) int last_errno; if (rel_path[0] == '/') - return strdup(rel_path); + return os_strdup(rel_path); for (;;) { - buf = malloc(len); + buf = os_malloc(len); if (buf == NULL) return NULL; cwd = getcwd(buf, len); if (cwd == NULL) { last_errno = errno; - free(buf); + os_free(buf); if (last_errno != ERANGE) return NULL; len *= 2; @@ -193,29 +215,51 @@ char * os_rel2abs_path(const char *rel_path) } } - cwd_len = strlen(cwd); - rel_len = strlen(rel_path); + cwd_len = os_strlen(cwd); + rel_len = os_strlen(rel_path); ret_len = cwd_len + 1 + rel_len + 1; - ret = malloc(ret_len); + ret = os_malloc(ret_len); if (ret) { - memcpy(ret, cwd, cwd_len); + os_memcpy(ret, cwd, cwd_len); ret[cwd_len] = '/'; - memcpy(ret + cwd_len + 1, rel_path, rel_len); + os_memcpy(ret + cwd_len + 1, rel_path, rel_len); ret[ret_len - 1] = '\0'; } - free(buf); + os_free(buf); return ret; } int os_program_init(void) { +#ifdef WPA_TRACE + dl_list_init(&alloc_list); +#endif /* WPA_TRACE */ return 0; } void os_program_deinit(void) { +#ifdef WPA_TRACE + struct os_alloc_trace *a; + unsigned long total = 0; + dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) { + total += a->len; + if (a->magic != ALLOC_MAGIC) { + wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x " + "len %lu", + a, a->magic, (unsigned long) a->len); + continue; + } + wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu", + a, (unsigned long) a->len); + wpa_trace_dump("memleak", a); + } + if (total) + wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes", + (unsigned long) total); +#endif /* WPA_TRACE */ } @@ -250,7 +294,7 @@ char * os_readfile(const char *name, size_t *len) *len = ftell(f); fseek(f, 0, SEEK_SET); - buf = malloc(*len); + buf = os_malloc(*len); if (buf == NULL) { fclose(f); return NULL; @@ -258,7 +302,7 @@ char * os_readfile(const char *name, size_t *len) if (fread(buf, 1, *len, f) != *len) { fclose(f); - free(buf); + os_free(buf); return NULL; } @@ -268,10 +312,12 @@ char * os_readfile(const char *name, size_t *len) } +#ifndef WPA_TRACE void * os_zalloc(size_t size) { return calloc(1, size); } +#endif /* WPA_TRACE */ size_t os_strlcpy(char *dest, const char *src, size_t siz) @@ -297,3 +343,95 @@ size_t os_strlcpy(char *dest, const char *src, size_t siz) return s - src - 1; } + + +#ifdef WPA_TRACE + +void * os_malloc(size_t size) +{ + struct os_alloc_trace *a; + a = malloc(sizeof(*a) + size); + if (a == NULL) + return NULL; + a->magic = ALLOC_MAGIC; + dl_list_add(&alloc_list, &a->list); + a->len = size; + wpa_trace_record(a); + return a + 1; +} + + +void * os_realloc(void *ptr, size_t size) +{ + struct os_alloc_trace *a; + size_t copy_len; + void *n; + + if (ptr == NULL) + return os_malloc(size); + + a = (struct os_alloc_trace *) ptr - 1; + if (a->magic != ALLOC_MAGIC) { + wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s", + a, a->magic, + a->magic == FREED_MAGIC ? " (already freed)" : ""); + wpa_trace_show("Invalid os_realloc() call"); + abort(); + } + n = os_malloc(size); + if (n == NULL) + return NULL; + copy_len = a->len; + if (copy_len > size) + copy_len = size; + os_memcpy(n, a + 1, copy_len); + os_free(ptr); + return n; +} + + +void os_free(void *ptr) +{ + struct os_alloc_trace *a; + + if (ptr == NULL) + return; + a = (struct os_alloc_trace *) ptr - 1; + if (a->magic != ALLOC_MAGIC) { + wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s", + a, a->magic, + a->magic == FREED_MAGIC ? " (already freed)" : ""); + wpa_trace_show("Invalid os_free() call"); + abort(); + } + dl_list_del(&a->list); + a->magic = FREED_MAGIC; + + wpa_trace_check_ref(ptr); + free(a); +} + + +void * os_zalloc(size_t size) +{ + void *ptr = os_malloc(size); + if (ptr) + os_memset(ptr, 0, size); + return ptr; +} + + +char * os_strdup(const char *s) +{ + size_t len; + char *d; + len = os_strlen(s); + d = os_malloc(len + 1); + if (d == NULL) + return NULL; + os_memcpy(d, s, len); + d[len] = '\0'; + return d; +} + +#endif /* WPA_TRACE */ diff --git a/contrib/wpa/src/utils/radiotap.c b/contrib/wpa/src/utils/radiotap.c new file mode 100644 index 0000000..804473f --- /dev/null +++ b/contrib/wpa/src/utils/radiotap.c @@ -0,0 +1,287 @@ +/* + * Radiotap parser + * + * Copyright 2007 Andy Green <andy@warmcat.com> + * + * 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. + * + * + * Modified for userspace by Johannes Berg <johannes@sipsolutions.net> + * I only modified some things on top to ease syncing should bugs be found. + */ + +#include "includes.h" + +#include "common.h" +#include "radiotap_iter.h" + +#define le16_to_cpu le_to_host16 +#define le32_to_cpu le_to_host32 +#define __le32 uint32_t +#define ulong unsigned long +#define unlikely(cond) (cond) +#define get_unaligned(p) \ +({ \ + struct packed_dummy_struct { \ + typeof(*(p)) __val; \ + } __attribute__((packed)) *__ptr = (void *) (p); \ + \ + __ptr->__val; \ +}) + +/* function prototypes and related defs are in radiotap_iter.h */ + +/** + * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization + * @iterator: radiotap_iterator to initialize + * @radiotap_header: radiotap header to parse + * @max_length: total length we can parse into (eg, whole packet length) + * + * Returns: 0 or a negative error code if there is a problem. + * + * This function initializes an opaque iterator struct which can then + * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap + * argument which is present in the header. It knows about extended + * present headers and handles them. + * + * How to use: + * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator + * struct ieee80211_radiotap_iterator (no need to init the struct beforehand) + * checking for a good 0 return code. Then loop calling + * __ieee80211_radiotap_iterator_next()... it returns either 0, + * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem. + * The iterator's @this_arg member points to the start of the argument + * associated with the current argument index that is present, which can be + * found in the iterator's @this_arg_index member. This arg index corresponds + * to the IEEE80211_RADIOTAP_... defines. + * + * Radiotap header length: + * You can find the CPU-endian total radiotap header length in + * iterator->max_length after executing ieee80211_radiotap_iterator_init() + * successfully. + * + * Alignment Gotcha: + * You must take care when dereferencing iterator.this_arg + * for multibyte types... the pointer is not aligned. Use + * get_unaligned((type *)iterator.this_arg) to dereference + * iterator.this_arg for type "type" safely on all arches. + * + * Example code: + * See Documentation/networking/radiotap-headers.txt + */ + +int ieee80211_radiotap_iterator_init( + struct ieee80211_radiotap_iterator *iterator, + struct ieee80211_radiotap_header *radiotap_header, + int max_length) +{ + /* Linux only supports version 0 radiotap format */ + if (radiotap_header->it_version) + return -EINVAL; + + /* sanity check for allowed length and radiotap length field */ + if (max_length < le16_to_cpu(get_unaligned(&radiotap_header->it_len))) + return -EINVAL; + + iterator->rtheader = radiotap_header; + iterator->max_length = le16_to_cpu(get_unaligned( + &radiotap_header->it_len)); + iterator->arg_index = 0; + iterator->bitmap_shifter = le32_to_cpu(get_unaligned( + &radiotap_header->it_present)); + iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header); + iterator->this_arg = NULL; + + /* find payload start allowing for extended bitmap(s) */ + + if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) { + while (le32_to_cpu(get_unaligned((__le32 *)iterator->arg)) & + (1<<IEEE80211_RADIOTAP_EXT)) { + iterator->arg += sizeof(u32); + + /* + * check for insanity where the present bitmaps + * keep claiming to extend up to or even beyond the + * stated radiotap header length + */ + + if (((ulong)iterator->arg - (ulong)iterator->rtheader) + > (ulong)iterator->max_length) + return -EINVAL; + } + + iterator->arg += sizeof(u32); + + /* + * no need to check again for blowing past stated radiotap + * header length, because ieee80211_radiotap_iterator_next + * checks it before it is dereferenced + */ + } + + /* we are all initialized happily */ + + return 0; +} + + +/** + * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg + * @iterator: radiotap_iterator to move to next arg (if any) + * + * Returns: 0 if there is an argument to handle, + * -ENOENT if there are no more args or -EINVAL + * if there is something else wrong. + * + * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*) + * in @this_arg_index and sets @this_arg to point to the + * payload for the field. It takes care of alignment handling and extended + * present fields. @this_arg can be changed by the caller (eg, + * incremented to move inside a compound argument like + * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in + * little-endian format whatever the endianess of your CPU. + * + * Alignment Gotcha: + * You must take care when dereferencing iterator.this_arg + * for multibyte types... the pointer is not aligned. Use + * get_unaligned((type *)iterator.this_arg) to dereference + * iterator.this_arg for type "type" safely on all arches. + */ + +int ieee80211_radiotap_iterator_next( + struct ieee80211_radiotap_iterator *iterator) +{ + + /* + * small length lookup table for all radiotap types we heard of + * starting from b0 in the bitmap, so we can walk the payload + * area of the radiotap header + * + * There is a requirement to pad args, so that args + * of a given length must begin at a boundary of that length + * -- but note that compound args are allowed (eg, 2 x u16 + * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not + * a reliable indicator of alignment requirement. + * + * upper nybble: content alignment for arg + * lower nybble: content length for arg + */ + + static const u8 rt_sizes[] = { + [IEEE80211_RADIOTAP_TSFT] = 0x88, + [IEEE80211_RADIOTAP_FLAGS] = 0x11, + [IEEE80211_RADIOTAP_RATE] = 0x11, + [IEEE80211_RADIOTAP_CHANNEL] = 0x24, + [IEEE80211_RADIOTAP_FHSS] = 0x22, + [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11, + [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11, + [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22, + [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22, + [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22, + [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11, + [IEEE80211_RADIOTAP_ANTENNA] = 0x11, + [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11, + [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11, + [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22, + [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22, + [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11, + [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11, + /* + * add more here as they are defined in + * include/net/ieee80211_radiotap.h + */ + }; + + /* + * for every radiotap entry we can at + * least skip (by knowing the length)... + */ + + while (iterator->arg_index < (int) sizeof(rt_sizes)) { + int hit = 0; + int pad; + + if (!(iterator->bitmap_shifter & 1)) + goto next_entry; /* arg not present */ + + /* + * arg is present, account for alignment padding + * 8-bit args can be at any alignment + * 16-bit args must start on 16-bit boundary + * 32-bit args must start on 32-bit boundary + * 64-bit args must start on 64-bit boundary + * + * note that total arg size can differ from alignment of + * elements inside arg, so we use upper nybble of length + * table to base alignment on + * + * also note: these alignments are ** relative to the + * start of the radiotap header **. There is no guarantee + * that the radiotap header itself is aligned on any + * kind of boundary. + * + * the above is why get_unaligned() is used to dereference + * multibyte elements from the radiotap area + */ + + pad = (((ulong)iterator->arg) - + ((ulong)iterator->rtheader)) & + ((rt_sizes[iterator->arg_index] >> 4) - 1); + + if (pad) + iterator->arg += + (rt_sizes[iterator->arg_index] >> 4) - pad; + + /* + * this is what we will return to user, but we need to + * move on first so next call has something fresh to test + */ + iterator->this_arg_index = iterator->arg_index; + iterator->this_arg = iterator->arg; + hit = 1; + + /* internally move on the size of this arg */ + iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; + + /* + * check for insanity where we are given a bitmap that + * claims to have more arg content than the length of the + * radiotap section. We will normally end up equalling this + * max_length on the last arg, never exceeding it. + */ + + if (((ulong)iterator->arg - (ulong)iterator->rtheader) > + (ulong) iterator->max_length) + return -EINVAL; + + next_entry: + iterator->arg_index++; + if (unlikely((iterator->arg_index & 31) == 0)) { + /* completed current u32 bitmap */ + if (iterator->bitmap_shifter & 1) { + /* b31 was set, there is more */ + /* move to next u32 bitmap */ + iterator->bitmap_shifter = le32_to_cpu( + get_unaligned(iterator->next_bitmap)); + iterator->next_bitmap++; + } else + /* no more bitmaps: end */ + iterator->arg_index = sizeof(rt_sizes); + } else /* just try the next bit */ + iterator->bitmap_shifter >>= 1; + + /* if we found a valid arg earlier, return it now */ + if (hit) + return 0; + } + + /* we don't know how to handle any more args, we're done */ + return -ENOENT; +} diff --git a/contrib/wpa/src/utils/radiotap.h b/contrib/wpa/src/utils/radiotap.h new file mode 100644 index 0000000..ba23ed3 --- /dev/null +++ b/contrib/wpa/src/utils/radiotap.h @@ -0,0 +1,242 @@ +/* $FreeBSD$ */ +/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */ + +/*- + * Copyright (c) 2003, 2004 David Young. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of David Young may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID + * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* + * Modifications to fit into the linux IEEE 802.11 stack, + * Mike Kershaw (dragorn@kismetwireless.net) + */ + +#ifndef IEEE80211RADIOTAP_H +#define IEEE80211RADIOTAP_H + +#include <stdint.h> + +/* Base version of the radiotap packet header data */ +#define PKTHDR_RADIOTAP_VERSION 0 + +/* A generic radio capture format is desirable. There is one for + * Linux, but it is neither rigidly defined (there were not even + * units given for some fields) nor easily extensible. + * + * I suggest the following extensible radio capture format. It is + * based on a bitmap indicating which fields are present. + * + * I am trying to describe precisely what the application programmer + * should expect in the following, and for that reason I tell the + * units and origin of each measurement (where it applies), or else I + * use sufficiently weaselly language ("is a monotonically nondecreasing + * function of...") that I cannot set false expectations for lawyerly + * readers. + */ + +/* The radio capture header precedes the 802.11 header. + * All data in the header is little endian on all platforms. + */ +struct ieee80211_radiotap_header { + uint8_t it_version; /* Version 0. Only increases + * for drastic changes, + * introduction of compatible + * new fields does not count. + */ + uint8_t it_pad; + uint16_t it_len; /* length of the whole + * header in bytes, including + * it_version, it_pad, + * it_len, and data fields. + */ + uint32_t it_present; /* A bitmap telling which + * fields are present. Set bit 31 + * (0x80000000) to extend the + * bitmap by another 32 bits. + * Additional extensions are made + * by setting bit 31. + */ +}; + +/* Name Data type Units + * ---- --------- ----- + * + * IEEE80211_RADIOTAP_TSFT __le64 microseconds + * + * Value in microseconds of the MAC's 64-bit 802.11 Time + * Synchronization Function timer when the first bit of the + * MPDU arrived at the MAC. For received frames, only. + * + * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap + * + * Tx/Rx frequency in MHz, followed by flags (see below). + * + * IEEE80211_RADIOTAP_FHSS uint16_t see below + * + * For frequency-hopping radios, the hop set (first byte) + * and pattern (second byte). + * + * IEEE80211_RADIOTAP_RATE u8 500kb/s + * + * Tx/Rx data rate + * + * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from + * one milliwatt (dBm) + * + * RF signal power at the antenna, decibel difference from + * one milliwatt. + * + * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from + * one milliwatt (dBm) + * + * RF noise power at the antenna, decibel difference from one + * milliwatt. + * + * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB) + * + * RF signal power at the antenna, decibel difference from an + * arbitrary, fixed reference. + * + * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB) + * + * RF noise power at the antenna, decibel difference from an + * arbitrary, fixed reference point. + * + * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless + * + * Quality of Barker code lock. Unitless. Monotonically + * nondecreasing with "better" lock strength. Called "Signal + * Quality" in datasheets. (Is there a standard way to measure + * this?) + * + * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless + * + * Transmit power expressed as unitless distance from max + * power set at factory calibration. 0 is max power. + * Monotonically nondecreasing with lower power levels. + * + * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB) + * + * Transmit power expressed as decibel distance from max power + * set at factory calibration. 0 is max power. Monotonically + * nondecreasing with lower power levels. + * + * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from + * one milliwatt (dBm) + * + * Transmit power expressed as dBm (decibels from a 1 milliwatt + * reference). This is the absolute power level measured at + * the antenna port. + * + * IEEE80211_RADIOTAP_FLAGS u8 bitmap + * + * Properties of transmitted and received frames. See flags + * defined below. + * + * IEEE80211_RADIOTAP_ANTENNA u8 antenna index + * + * Unitless indication of the Rx/Tx antenna for this packet. + * The first antenna is antenna 0. + * + * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap + * + * Properties of received frames. See flags defined below. + * + * IEEE80211_RADIOTAP_TX_FLAGS uint16_t bitmap + * + * Properties of transmitted frames. See flags defined below. + * + * IEEE80211_RADIOTAP_RTS_RETRIES u8 data + * + * Number of rts retries a transmitted frame used. + * + * IEEE80211_RADIOTAP_DATA_RETRIES u8 data + * + * Number of unicast retries a transmitted frame used. + * + */ +enum ieee80211_radiotap_type { + IEEE80211_RADIOTAP_TSFT = 0, + IEEE80211_RADIOTAP_FLAGS = 1, + IEEE80211_RADIOTAP_RATE = 2, + IEEE80211_RADIOTAP_CHANNEL = 3, + IEEE80211_RADIOTAP_FHSS = 4, + IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, + IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, + IEEE80211_RADIOTAP_LOCK_QUALITY = 7, + IEEE80211_RADIOTAP_TX_ATTENUATION = 8, + IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, + IEEE80211_RADIOTAP_DBM_TX_POWER = 10, + IEEE80211_RADIOTAP_ANTENNA = 11, + IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, + IEEE80211_RADIOTAP_DB_ANTNOISE = 13, + IEEE80211_RADIOTAP_RX_FLAGS = 14, + IEEE80211_RADIOTAP_TX_FLAGS = 15, + IEEE80211_RADIOTAP_RTS_RETRIES = 16, + IEEE80211_RADIOTAP_DATA_RETRIES = 17, + IEEE80211_RADIOTAP_EXT = 31 +}; + +/* Channel flags. */ +#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */ +#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */ +#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */ +#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */ +#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */ +#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ +#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ +#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ + +/* For IEEE80211_RADIOTAP_FLAGS */ +#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received + * during CFP + */ +#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received + * with short + * preamble + */ +#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received + * with WEP encryption + */ +#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received + * with fragmentation + */ +#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ +#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between + * 802.11 header and payload + * (to 32-bit boundary) + */ +/* For IEEE80211_RADIOTAP_RX_FLAGS */ +#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ + +/* For IEEE80211_RADIOTAP_TX_FLAGS */ +#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive + * retries */ +#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ +#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ + +#endif /* IEEE80211_RADIOTAP_H */ diff --git a/contrib/wpa/src/utils/radiotap_iter.h b/contrib/wpa/src/utils/radiotap_iter.h new file mode 100644 index 0000000..92a798a --- /dev/null +++ b/contrib/wpa/src/utils/radiotap_iter.h @@ -0,0 +1,41 @@ +#ifndef __RADIOTAP_ITER_H +#define __RADIOTAP_ITER_H + +#include "radiotap.h" + +/* Radiotap header iteration + * implemented in radiotap.c + */ +/** + * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args + * @rtheader: pointer to the radiotap header we are walking through + * @max_length: length of radiotap header in cpu byte ordering + * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg + * @this_arg: pointer to current radiotap arg + * @arg_index: internal next argument index + * @arg: internal next argument pointer + * @next_bitmap: internal pointer to next present u32 + * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present + */ + +struct ieee80211_radiotap_iterator { + struct ieee80211_radiotap_header *rtheader; + int max_length; + int this_arg_index; + unsigned char *this_arg; + + int arg_index; + unsigned char *arg; + uint32_t *next_bitmap; + uint32_t bitmap_shifter; +}; + +extern int ieee80211_radiotap_iterator_init( + struct ieee80211_radiotap_iterator *iterator, + struct ieee80211_radiotap_header *radiotap_header, + int max_length); + +extern int ieee80211_radiotap_iterator_next( + struct ieee80211_radiotap_iterator *iterator); + +#endif /* __RADIOTAP_ITER_H */ diff --git a/contrib/wpa/src/utils/trace.c b/contrib/wpa/src/utils/trace.c new file mode 100644 index 0000000..bb3eb24 --- /dev/null +++ b/contrib/wpa/src/utils/trace.c @@ -0,0 +1,329 @@ +/* + * Backtrace debugging + * Copyright (c) 2009, 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 "trace.h" + +#ifdef WPA_TRACE + +static struct dl_list active_references = +{ &active_references, &active_references }; + +#ifdef WPA_TRACE_BFD +#include <bfd.h> +#ifdef __linux__ +#include <demangle.h> +#else /* __linux__ */ +#include <libiberty/demangle.h> +#endif /* __linux__ */ + +static char *prg_fname = NULL; +static bfd *cached_abfd = NULL; +static asymbol **syms = NULL; + +static void get_prg_fname(void) +{ + char exe[50], fname[512]; + int len; + os_snprintf(exe, sizeof(exe) - 1, "/proc/%u/exe", getpid()); + len = readlink(exe, fname, sizeof(fname) - 1); + if (len < 0 || len >= (int) sizeof(fname)) { + perror("readlink"); + return; + } + fname[len] = '\0'; + prg_fname = strdup(fname); +} + + +static bfd * open_bfd(const char *fname) +{ + bfd *abfd; + char **matching; + + abfd = bfd_openr(prg_fname, NULL); + if (abfd == NULL) { + wpa_printf(MSG_INFO, "bfd_openr failed"); + return NULL; + } + + if (bfd_check_format(abfd, bfd_archive)) { + wpa_printf(MSG_INFO, "bfd_check_format failed"); + bfd_close(abfd); + return NULL; + } + + if (!bfd_check_format_matches(abfd, bfd_object, &matching)) { + wpa_printf(MSG_INFO, "bfd_check_format_matches failed"); + free(matching); + bfd_close(abfd); + return NULL; + } + + return abfd; +} + + +static void read_syms(bfd *abfd) +{ + long storage, symcount; + bfd_boolean dynamic = FALSE; + + if (syms) + return; + + if (!(bfd_get_file_flags(abfd) & HAS_SYMS)) { + wpa_printf(MSG_INFO, "No symbols"); + return; + } + + storage = bfd_get_symtab_upper_bound(abfd); + if (storage == 0) { + storage = bfd_get_dynamic_symtab_upper_bound(abfd); + dynamic = TRUE; + } + if (storage < 0) { + wpa_printf(MSG_INFO, "Unknown symtab upper bound"); + return; + } + + syms = malloc(storage); + if (syms == NULL) { + wpa_printf(MSG_INFO, "Failed to allocate memory for symtab " + "(%ld bytes)", storage); + return; + } + if (dynamic) + symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); + else + symcount = bfd_canonicalize_symtab(abfd, syms); + if (symcount < 0) { + wpa_printf(MSG_INFO, "Failed to canonicalize %ssymtab", + dynamic ? "dynamic " : ""); + free(syms); + syms = NULL; + return; + } +} + + +struct bfd_data { + bfd_vma pc; + bfd_boolean found; + const char *filename; + const char *function; + unsigned int line; +}; + + +static void find_addr_sect(bfd *abfd, asection *section, void *obj) +{ + struct bfd_data *data = obj; + bfd_vma vma; + bfd_size_type size; + + if (data->found) + return; + + if (!(bfd_get_section_vma(abfd, section))) + return; + + vma = bfd_get_section_vma(abfd, section); + if (data->pc < vma) + return; + + size = bfd_get_section_size(section); + if (data->pc >= vma + size) + return; + + data->found = bfd_find_nearest_line(abfd, section, syms, + data->pc - vma, + &data->filename, + &data->function, + &data->line); +} + + +static void wpa_trace_bfd_addr(void *pc) +{ + bfd *abfd = cached_abfd; + struct bfd_data data; + const char *name; + char *aname = NULL; + const char *filename; + + if (abfd == NULL) + return; + + data.pc = (bfd_vma) pc; + data.found = FALSE; + bfd_map_over_sections(abfd, find_addr_sect, &data); + + if (!data.found) + return; + + do { + if (data.function) + aname = bfd_demangle(abfd, data.function, + DMGL_ANSI | DMGL_PARAMS); + name = aname ? aname : data.function; + filename = data.filename; + if (filename) { + char *end = os_strrchr(filename, '/'); + int i = 0; + while (*filename && *filename == prg_fname[i] && + filename <= end) { + filename++; + i++; + } + } + wpa_printf(MSG_INFO, " %s() %s:%u", + name, filename, data.line); + free(aname); + + data.found = bfd_find_inliner_info(abfd, &data.filename, + &data.function, &data.line); + } while (data.found); +} + + +static const char * wpa_trace_bfd_addr2func(void *pc) +{ + bfd *abfd = cached_abfd; + struct bfd_data data; + + if (abfd == NULL) + return NULL; + + data.pc = (bfd_vma) pc; + data.found = FALSE; + bfd_map_over_sections(abfd, find_addr_sect, &data); + + if (!data.found) + return NULL; + + return data.function; +} + + +static void wpa_trace_bfd_init(void) +{ + if (!prg_fname) { + get_prg_fname(); + if (!prg_fname) + return; + } + + if (!cached_abfd) { + cached_abfd = open_bfd(prg_fname); + if (!cached_abfd) { + wpa_printf(MSG_INFO, "Failed to open bfd"); + return; + } + } + + read_syms(cached_abfd); + if (!syms) { + wpa_printf(MSG_INFO, "Failed to read symbols"); + return; + } +} + + +void wpa_trace_dump_funcname(const char *title, void *pc) +{ + wpa_printf(MSG_INFO, "WPA_TRACE: %s: %p", title, pc); + wpa_trace_bfd_init(); + wpa_trace_bfd_addr(pc); +} + +#else /* WPA_TRACE_BFD */ + +#define wpa_trace_bfd_init() do { } while (0) +#define wpa_trace_bfd_addr(pc) do { } while (0) +#define wpa_trace_bfd_addr2func(pc) NULL + +#endif /* WPA_TRACE_BFD */ + +void wpa_trace_dump_func(const char *title, void **btrace, int btrace_num) +{ + char **sym; + int i; + enum { TRACE_HEAD, TRACE_RELEVANT, TRACE_TAIL } state; + + wpa_trace_bfd_init(); + wpa_printf(MSG_INFO, "WPA_TRACE: %s - START", title); + sym = backtrace_symbols(btrace, btrace_num); + state = TRACE_HEAD; + for (i = 0; i < btrace_num; i++) { + const char *func = wpa_trace_bfd_addr2func(btrace[i]); + if (state == TRACE_HEAD && func && + (os_strcmp(func, "wpa_trace_add_ref_func") == 0 || + os_strcmp(func, "wpa_trace_check_ref") == 0 || + os_strcmp(func, "wpa_trace_show") == 0)) + continue; + if (state == TRACE_TAIL && sym && sym[i] && + os_strstr(sym[i], "__libc_start_main")) + break; + if (state == TRACE_HEAD) + state = TRACE_RELEVANT; + if (sym) + wpa_printf(MSG_INFO, "[%d]: %s", i, sym[i]); + else + wpa_printf(MSG_INFO, "[%d]: ?? [%p]", i, btrace[i]); + wpa_trace_bfd_addr(btrace[i]); + if (state == TRACE_RELEVANT && func && + os_strcmp(func, "main") == 0) + state = TRACE_TAIL; + } + free(sym); + wpa_printf(MSG_INFO, "WPA_TRACE: %s - END", title); +} + + +void wpa_trace_show(const char *title) +{ + struct info { + WPA_TRACE_INFO + } info; + wpa_trace_record(&info); + wpa_trace_dump(title, &info); +} + + +void wpa_trace_add_ref_func(struct wpa_trace_ref *ref, const void *addr) +{ + if (addr == NULL) + return; + ref->addr = addr; + wpa_trace_record(ref); + dl_list_add(&active_references, &ref->list); +} + + +void wpa_trace_check_ref(const void *addr) +{ + struct wpa_trace_ref *ref; + dl_list_for_each(ref, &active_references, struct wpa_trace_ref, list) { + if (addr != ref->addr) + continue; + wpa_trace_show("Freeing referenced memory"); + wpa_trace_dump("Reference registration", ref); + abort(); + } +} + +#endif /* WPA_TRACE */ diff --git a/contrib/wpa/src/utils/trace.h b/contrib/wpa/src/utils/trace.h new file mode 100644 index 0000000..22d3de0 --- /dev/null +++ b/contrib/wpa/src/utils/trace.h @@ -0,0 +1,74 @@ +/* + * Backtrace debugging + * Copyright (c) 2009, 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. + */ + +#ifndef TRACE_H +#define TRACE_H + +#define WPA_TRACE_LEN 16 + +#ifdef WPA_TRACE +#include <execinfo.h> + +#include "list.h" + +#define WPA_TRACE_INFO void *btrace[WPA_TRACE_LEN]; int btrace_num; + +struct wpa_trace_ref { + struct dl_list list; + const void *addr; + WPA_TRACE_INFO +}; +#define WPA_TRACE_REF(name) struct wpa_trace_ref wpa_trace_ref_##name + +#define wpa_trace_dump(title, ptr) \ + wpa_trace_dump_func((title), (ptr)->btrace, (ptr)->btrace_num) +void wpa_trace_dump_func(const char *title, void **btrace, int btrace_num); +#define wpa_trace_record(ptr) \ + (ptr)->btrace_num = backtrace((ptr)->btrace, WPA_TRACE_LEN) +void wpa_trace_show(const char *title); +#define wpa_trace_add_ref(ptr, name, addr) \ + wpa_trace_add_ref_func(&(ptr)->wpa_trace_ref_##name, (addr)) +void wpa_trace_add_ref_func(struct wpa_trace_ref *ref, const void *addr); +#define wpa_trace_remove_ref(ptr, name, addr) \ + do { \ + if ((addr)) \ + dl_list_del(&(ptr)->wpa_trace_ref_##name.list); \ + } while (0) +void wpa_trace_check_ref(const void *addr); + +#else /* WPA_TRACE */ + +#define WPA_TRACE_INFO +#define WPA_TRACE_REF(n) +#define wpa_trace_dump(title, ptr) do { } while (0) +#define wpa_trace_record(ptr) do { } while (0) +#define wpa_trace_show(title) do { } while (0) +#define wpa_trace_add_ref(ptr, name, addr) do { } while (0) +#define wpa_trace_remove_ref(ptr, name, addr) do { } while (0) +#define wpa_trace_check_ref(addr) do { } while (0) + +#endif /* WPA_TRACE */ + + +#ifdef WPA_TRACE_BFD + +void wpa_trace_dump_funcname(const char *title, void *pc); + +#else /* WPA_TRACE_BFD */ + +#define wpa_trace_dump_funcname(title, pc) do { } while (0) + +#endif /* WPA_TRACE_BFD */ + +#endif /* TRACE_H */ diff --git a/contrib/wpa/src/utils/uuid.c b/contrib/wpa/src/utils/uuid.c index 620d3d6..d8cc267 100644 --- a/contrib/wpa/src/utils/uuid.c +++ b/contrib/wpa/src/utils/uuid.c @@ -15,8 +15,6 @@ #include "includes.h" #include "common.h" -#include "crypto.h" -#include "sha1.h" #include "uuid.h" int uuid_str2bin(const char *str, u8 *bin) @@ -77,31 +75,3 @@ int is_nil_uuid(const u8 *uuid) return 0; return 1; } - - -void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid) -{ - const u8 *addr[2]; - size_t len[2]; - u8 hash[SHA1_MAC_LEN]; - u8 nsid[16] = { - 0x52, 0x64, 0x80, 0xf8, - 0xc9, 0x9b, - 0x4b, 0xe5, - 0xa6, 0x55, - 0x58, 0xed, 0x5f, 0x5d, 0x60, 0x84 - }; - - addr[0] = nsid; - len[0] = sizeof(nsid); - addr[1] = mac_addr; - len[1] = 6; - sha1_vector(2, addr, len, hash); - os_memcpy(uuid, hash, 16); - - /* Version: 5 = named-based version using SHA-1 */ - uuid[6] = (5 << 4) | (uuid[6] & 0x0f); - - /* Variant specified in RFC 4122 */ - uuid[8] = 0x80 | (uuid[8] & 0x3f); -} diff --git a/contrib/wpa/src/utils/uuid.h b/contrib/wpa/src/utils/uuid.h index 9fc2ba0..0759165 100644 --- a/contrib/wpa/src/utils/uuid.h +++ b/contrib/wpa/src/utils/uuid.h @@ -20,6 +20,5 @@ int uuid_str2bin(const char *str, u8 *bin); int uuid_bin2str(const u8 *bin, char *str, size_t max_len); int is_nil_uuid(const u8 *uuid); -void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid); #endif /* UUID_H */ diff --git a/contrib/wpa/src/utils/wpa_debug.c b/contrib/wpa/src/utils/wpa_debug.c index 0f46aee..6f6fc69 100644 --- a/contrib/wpa/src/utils/wpa_debug.c +++ b/contrib/wpa/src/utils/wpa_debug.c @@ -18,6 +18,8 @@ #ifdef CONFIG_DEBUG_SYSLOG #include <syslog.h> + +static int wpa_debug_syslog = 0; #endif /* CONFIG_DEBUG_SYSLOG */ @@ -27,7 +29,6 @@ static FILE *out_file = NULL; int wpa_debug_level = MSG_INFO; int wpa_debug_show_keys = 0; int wpa_debug_timestamp = 0; -int wpa_debug_syslog = 0; #ifndef CONFIG_NO_STDOUT_DEBUG @@ -49,23 +50,22 @@ void wpa_debug_print_timestamp(void) printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec); } + +#ifdef CONFIG_DEBUG_SYSLOG void wpa_debug_open_syslog(void) { -#ifdef CONFIG_DEBUG_SYSLOG openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_DAEMON); wpa_debug_syslog++; -#endif } + void wpa_debug_close_syslog(void) { -#ifdef CONFIG_DEBUG_SYSLOG if (wpa_debug_syslog) closelog(); -#endif } -#ifdef CONFIG_DEBUG_SYSLOG + static int syslog_priority(int level) { switch (level) { @@ -390,6 +390,9 @@ void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, va_end(ap); if (hostapd_logger_cb) hostapd_logger_cb(ctx, addr, module, level, buf, len); + else if (addr) + wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s", + MAC2STR(addr), buf); else wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf); os_free(buf); diff --git a/contrib/wpa/src/utils/wpa_debug.h b/contrib/wpa/src/utils/wpa_debug.h index b4010d5..6e5e79e 100644 --- a/contrib/wpa/src/utils/wpa_debug.h +++ b/contrib/wpa/src/utils/wpa_debug.h @@ -221,6 +221,23 @@ enum hostapd_logger_level { }; +#ifdef CONFIG_DEBUG_SYSLOG + +void wpa_debug_open_syslog(void); +void wpa_debug_close_syslog(void); + +#else /* CONFIG_DEBUG_SYSLOG */ + +static inline void wpa_debug_open_syslog(void) +{ +} + +static inline void wpa_debug_close_syslog(void) +{ +} + +#endif /* CONFIG_DEBUG_SYSLOG */ + #ifdef EAPOL_TEST #define WPA_ASSERT(a) \ diff --git a/contrib/wpa/src/utils/wpabuf.c b/contrib/wpa/src/utils/wpabuf.c index 8181912..eda779e 100644 --- a/contrib/wpa/src/utils/wpabuf.c +++ b/contrib/wpa/src/utils/wpabuf.c @@ -15,13 +15,37 @@ #include "includes.h" #include "common.h" +#include "trace.h" #include "wpabuf.h" +#ifdef WPA_TRACE +#define WPABUF_MAGIC 0x51a974e3 + +struct wpabuf_trace { + unsigned int magic; +}; + +static struct wpabuf_trace * wpabuf_get_trace(const struct wpabuf *buf) +{ + return (struct wpabuf_trace *) + ((const u8 *) buf - sizeof(struct wpabuf_trace)); +} +#endif /* WPA_TRACE */ + + static void wpabuf_overflow(const struct wpabuf *buf, size_t len) { +#ifdef WPA_TRACE + struct wpabuf_trace *trace = wpabuf_get_trace(buf); + if (trace->magic != WPABUF_MAGIC) { + wpa_printf(MSG_ERROR, "wpabuf: invalid magic %x", + trace->magic); + } +#endif /* WPA_TRACE */ wpa_printf(MSG_ERROR, "wpabuf %p (size=%lu used=%lu) overflow len=%lu", buf, (unsigned long) buf->size, (unsigned long) buf->used, (unsigned long) len); + wpa_trace_show("wpabuf overflow"); abort(); } @@ -29,10 +53,25 @@ 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; +#ifdef WPA_TRACE + struct wpabuf_trace *trace; +#endif /* WPA_TRACE */ + if (buf == NULL) { *_buf = wpabuf_alloc(add_len); return *_buf == NULL ? -1 : 0; } + +#ifdef WPA_TRACE + trace = wpabuf_get_trace(buf); + if (trace->magic != WPABUF_MAGIC) { + wpa_printf(MSG_ERROR, "wpabuf: invalid magic %x", + trace->magic); + wpa_trace_show("wpabuf_resize invalid magic"); + abort(); + } +#endif /* WPA_TRACE */ + if (buf->used + add_len > buf->size) { unsigned char *nbuf; if (buf->ext_data) { @@ -42,6 +81,18 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len) os_memset(nbuf + buf->used, 0, add_len); buf->ext_data = nbuf; } else { +#ifdef WPA_TRACE + nbuf = os_realloc(trace, sizeof(struct wpabuf_trace) + + sizeof(struct wpabuf) + + buf->used + add_len); + if (nbuf == NULL) + return -1; + trace = (struct wpabuf_trace *) nbuf; + buf = (struct wpabuf *) (trace + 1); + os_memset(nbuf + sizeof(struct wpabuf_trace) + + sizeof(struct wpabuf) + buf->used, 0, + add_len); +#else /* WPA_TRACE */ nbuf = os_realloc(buf, sizeof(struct wpabuf) + buf->used + add_len); if (nbuf == NULL) @@ -49,6 +100,7 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len) buf = (struct wpabuf *) nbuf; os_memset(nbuf + sizeof(struct wpabuf) + buf->used, 0, add_len); +#endif /* WPA_TRACE */ *_buf = buf; } buf->size = buf->used + add_len; @@ -65,9 +117,20 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len) */ struct wpabuf * wpabuf_alloc(size_t len) { +#ifdef WPA_TRACE + struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) + + sizeof(struct wpabuf) + len); + struct wpabuf *buf; + if (trace == NULL) + return NULL; + trace->magic = WPABUF_MAGIC; + buf = (struct wpabuf *) (trace + 1); +#else /* WPA_TRACE */ struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf) + len); if (buf == NULL) return NULL; +#endif /* WPA_TRACE */ + buf->size = len; return buf; } @@ -75,9 +138,19 @@ struct wpabuf * wpabuf_alloc(size_t len) struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len) { +#ifdef WPA_TRACE + struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) + + sizeof(struct wpabuf)); + struct wpabuf *buf; + if (trace == NULL) + return NULL; + trace->magic = WPABUF_MAGIC; + buf = (struct wpabuf *) (trace + 1); +#else /* WPA_TRACE */ struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf)); if (buf == NULL) return NULL; +#endif /* WPA_TRACE */ buf->size = len; buf->used = len; @@ -111,10 +184,25 @@ struct wpabuf * wpabuf_dup(const struct wpabuf *src) */ void wpabuf_free(struct wpabuf *buf) { +#ifdef WPA_TRACE + struct wpabuf_trace *trace; + if (buf == NULL) + return; + trace = wpabuf_get_trace(buf); + if (trace->magic != WPABUF_MAGIC) { + wpa_printf(MSG_ERROR, "wpabuf_free: invalid magic %x", + trace->magic); + wpa_trace_show("wpabuf_free magic mismatch"); + abort(); + } + os_free(buf->ext_data); + os_free(trace); +#else /* WPA_TRACE */ if (buf == NULL) return; os_free(buf->ext_data); os_free(buf); +#endif /* WPA_TRACE */ } diff --git a/contrib/wpa/src/utils/wpabuf.h b/contrib/wpa/src/utils/wpabuf.h index bd8f09e..a150455 100644 --- a/contrib/wpa/src/utils/wpabuf.h +++ b/contrib/wpa/src/utils/wpabuf.h @@ -111,6 +111,12 @@ static inline void wpabuf_put_u8(struct wpabuf *buf, u8 data) *pos = data; } +static inline void wpabuf_put_le16(struct wpabuf *buf, u16 data) +{ + u8 *pos = wpabuf_put(buf, 2); + WPA_PUT_LE16(pos, data); +} + static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data) { u8 *pos = wpabuf_put(buf, 2); |