diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52cdce5..90216a8 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,9 +13,6 @@ SET(SOURCES storage/datastorage.c include/datastorage.h - storage/uface.c - include/uface.h - network/networksocket.c include/networksocket.h @@ -28,6 +25,9 @@ SET(SOURCES utils/ubus.c include/ubus.h + utils/msghandler.c + include/msghandler.h + utils/dawn_uci.c include/dawn_uci.h @@ -37,6 +37,9 @@ SET(SOURCES include/utils.h utils/utils.c + utils/mac_utils.c + include/mac_utils.h + include/tcpsocket.h network/tcpsocket.c @@ -48,23 +51,31 @@ SET(SOURCES SET(SOURCES_TEST_STORAGE test/test_storage.c + include/test_storage.h - include/uface.h + include/ubus.h utils/utils.c include/utils.h + utils/mac_utils.c + include/mac_utils.h + storage/datastorage.c include/datastorage.h utils/ieee80211_utils.c include/ieee80211_utils.h) +SET(SOURCES_TEST_HEADER + test/test_header.c) + SET(LIBS ubox ubus json-c blobmsg_json uci gcrypt iwinfo) ADD_EXECUTABLE(dawn ${SOURCES}) ADD_EXECUTABLE(test_storage ${SOURCES_TEST_STORAGE}) +ADD_EXECUTABLE(test_header ${SOURCES_TEST_HEADER}) TARGET_LINK_LIBRARIES(dawn ${LIBS}) diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c index f488c8e..7ce7d8c 100644 --- a/src/crypto/crypto.c +++ b/src/crypto/crypto.c @@ -1,11 +1,9 @@ // based on: // https://github.com/vedantk/gcrypt-example/blob/master/gcry.cc -#include "crypto.h" - -#include #include -#include + +#include "crypto.h" #define GCRY_CIPHER GCRY_CIPHER_AES128 // Pick the cipher here #define GCRY_C_MODE GCRY_CIPHER_MODE_ECB // Pick the cipher mode here @@ -70,7 +68,7 @@ char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int *out_length) { if (!out){ fprintf(stderr, "gcry_cipher_encrypt error: not enought memory\n"); return NULL; - } + } gcry_error_handle = gcry_cipher_encrypt(gcry_cipher_hd, out, msg_length, msg, msg_length); if (gcry_error_handle) { fprintf(stderr, "gcry_cipher_encrypt failed: %s/%s\n", @@ -91,7 +89,7 @@ char *gcrypt_decrypt_msg(char *msg, size_t msg_length) { if (!out_buffer){ fprintf(stderr, "gcry_cipher_decrypt error: not enought memory\n"); return NULL; - } + } gcry_error_handle = gcry_cipher_decrypt(gcry_cipher_hd, out_buffer, msg_length, msg, msg_length); if (gcry_error_handle) { fprintf(stderr, "gcry_cipher_decrypt failed: %s/%s\n", diff --git a/src/include/broadcastsocket.h b/src/include/broadcastsocket.h index bd93409..610fded 100644 --- a/src/include/broadcastsocket.h +++ b/src/include/broadcastsocket.h @@ -1,6 +1,7 @@ #ifndef __DAWN_BROADCASTSOCKET_H #define __DAWN_BROADCASTSOCKET_H +#include /** * Function that setups a broadcast socket. diff --git a/src/include/crypto.h b/src/include/crypto.h index 178e7a9..d97e5ef 100644 --- a/src/include/crypto.h +++ b/src/include/crypto.h @@ -1,7 +1,7 @@ #ifndef DAWN_CRYPTO_H #define DAWN_CRYPTO_H -#include +#include /** * Initialize gcrypt. diff --git a/src/include/datastorage.h b/src/include/datastorage.h index cecc1f5..6d58046 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -3,16 +3,11 @@ #include #include -#include -#include -#include #include -#include #include -#ifndef ETH_ALEN -#define ETH_ALEN 6 -#endif +#include "mac_utils.h" +#include "utils.h" /* Mac */ @@ -20,7 +15,7 @@ #define MAC_LIST_LENGTH 100 // ---------------- Global variables ---------------- -uint8_t mac_list[MAC_LIST_LENGTH][ETH_ALEN]; +extern uint8_t mac_list[][ETH_ALEN]; // ---------------- Functions ---------- void insert_macs_from_file(); @@ -29,39 +24,37 @@ int insert_to_maclist(uint8_t mac[]); int mac_in_maclist(uint8_t mac[]); -int mac_is_equal(uint8_t addr1[], uint8_t addr2[]); -int mac_is_greater(uint8_t addr1[], uint8_t addr2[]); - -/* Metric */ +// ---------------- Global variables ---------------- +/*** Metrics and configuration data ***/ // ---------------- Structs ---------------- struct probe_metric_s { - int ap_weight; - int ht_support; - int vht_support; - int no_ht_support; - int no_vht_support; - int rssi; - int low_rssi; - int freq; - int chan_util; - int max_chan_util; - int rssi_val; - int low_rssi_val; - int chan_util_val; - int max_chan_util_val; + int ap_weight; // TODO: Never evaluated? + int ht_support; // eval_probe_metric()() + int vht_support; // eval_probe_metric()() + int no_ht_support; // eval_probe_metric()() + int no_vht_support; // eval_probe_metric()() + int rssi; // eval_probe_metric()() + int low_rssi; // eval_probe_metric()() + int freq; // eval_probe_metric()() + int chan_util; // eval_probe_metric()() + int max_chan_util; // eval_probe_metric()() + int rssi_val; // eval_probe_metric()() + int low_rssi_val; // eval_probe_metric()() + int chan_util_val; // eval_probe_metric()() + int max_chan_util_val; // eval_probe_metric()() int min_probe_count; - int bandwidth_threshold; - int use_station_count; - int max_station_diff; + int bandwidth_threshold; // kick_clients() + int use_station_count; // better_ap_available() + int max_station_diff; // compare_station_count() <- better_ap_available() int eval_probe_req; int eval_auth_req; int eval_assoc_req; int deny_auth_reason; int deny_assoc_reason; int use_driver_recog; - int min_kick_count; + int min_kick_count; // kick_clients() int chan_util_avg_period; int set_hostapd_nr; int kicking; @@ -98,12 +91,18 @@ struct network_config_s { int bandwidth; }; -// ---------------- Global variables ---------------- -struct network_config_s network_config; -struct time_config_s timeout_config; +extern struct network_config_s network_config; +extern struct time_config_s timeout_config; +extern struct probe_metric_s dawn_metric; -struct probe_metric_s dawn_metric; -extern int probe_entry_last; +/*** Core DAWN data structures for tracking network devices and status ***/ +// Define this to remove printing / reporing of fields, and hence observe +// which fields are evaluated in use. +// #define DAWN_NO_OUTPUT + +// TODO notes: +// Never used? = No code reference +// Never evaluated? = Set and passed in ubus, etc but never evaluated for outcomes /* Probe, Auth, Assoc */ @@ -111,16 +110,18 @@ extern int probe_entry_last; typedef struct probe_entry_s { uint8_t bssid_addr[ETH_ALEN]; uint8_t client_addr[ETH_ALEN]; - uint8_t target_addr[ETH_ALEN]; - uint32_t signal; - uint32_t freq; - uint8_t ht_capabilities; - uint8_t vht_capabilities; - time_t time; + uint8_t target_addr[ETH_ALEN]; // TODO: Never evaluated? + uint32_t signal; // eval_probe_metric() + uint32_t freq; // eval_probe_metric() + uint8_t ht_capabilities; // eval_probe_metric() + uint8_t vht_capabilities; // eval_probe_metric() + time_t time; // remove_old...entries int counter; - int deny_counter; - uint8_t max_supp_datarate; - uint8_t min_supp_datarate; +#ifndef DAWN_NO_OUTPUT + int deny_counter; // TODO: Never used? + uint8_t max_supp_datarate; // TODO: Never used? + uint8_t min_supp_datarate; // TODO: Never used? +#endif uint32_t rcpi; uint32_t rsni; } probe_entry; @@ -128,10 +129,10 @@ typedef struct probe_entry_s { typedef struct auth_entry_s { uint8_t bssid_addr[ETH_ALEN]; uint8_t client_addr[ETH_ALEN]; - uint8_t target_addr[ETH_ALEN]; - uint32_t signal; - uint32_t freq; - time_t time; + uint8_t target_addr[ETH_ALEN]; // TODO: Never evaluated? + uint32_t signal; // TODO: Never evaluated? + uint32_t freq; // TODO: Never evaluated? + time_t time; // Never used for removal? int counter; } auth_entry; @@ -150,13 +151,13 @@ typedef struct auth_entry_s assoc_entry; #define NEIGHBOR_REPORT_LEN 200 // ---------------- Global variables ---------------- -struct auth_entry_s denied_req_array[DENY_REQ_ARRAY_LEN]; +extern struct auth_entry_s denied_req_array[]; extern int denied_req_last; -pthread_mutex_t denied_array_mutex; +extern pthread_mutex_t denied_array_mutex; -struct probe_entry_s probe_array[PROBE_ARRAY_LEN]; +extern struct probe_entry_s probe_array[]; extern int probe_entry_last; -pthread_mutex_t probe_array_mutex; +extern pthread_mutex_t probe_array_mutex; // ---------------- Functions ---------------- probe_entry insert_to_array(probe_entry entry, int inc_counter, int save_80211k, int is_beacon); @@ -192,39 +193,39 @@ void print_auth_entry(auth_entry entry); typedef struct client_s { uint8_t bssid_addr[ETH_ALEN]; uint8_t client_addr[ETH_ALEN]; - char signature[SIGNATURE_LEN]; - uint8_t ht_supported; - uint8_t vht_supported; - uint32_t freq; - uint8_t auth; - uint8_t assoc; - uint8_t authorized; - uint8_t preauth; - uint8_t wds; - uint8_t wmm; - uint8_t ht; - uint8_t vht; - uint8_t wps; - uint8_t mfp; - time_t time; - uint32_t aid; - uint32_t kick_count; + char signature[SIGNATURE_LEN]; // TODO: Never evaluated? + uint8_t ht_supported; // TODO: Never evaluated? + uint8_t vht_supported; // TODO: Never evaluated? + uint32_t freq; // TODO: Never evaluated? + uint8_t auth; // TODO: Never evaluated? + uint8_t assoc; // TODO: Never evaluated? + uint8_t authorized; // TODO: Never evaluated? + uint8_t preauth; // TODO: Never evaluated? + uint8_t wds; // TODO: Never evaluated? + uint8_t wmm; // TODO: Never evaluated? + uint8_t ht; // TODO: Never evaluated? + uint8_t vht; // TODO: Never evaluated? + uint8_t wps; // TODO: Never evaluated? + uint8_t mfp; // TODO: Never evaluated? + time_t time; // remove_old...entries + uint32_t aid; // TODO: Never evaluated? + uint32_t kick_count; // kick_clients() uint8_t rrm_enabled_capa; //the first byte is enough } client; typedef struct ap_s { uint8_t bssid_addr[ETH_ALEN]; - uint32_t freq; - uint8_t ht_support; - uint8_t vht_support; - uint32_t channel_utilization; - time_t time; - uint32_t station_count; - uint8_t ssid[SSID_MAX_LEN]; + uint32_t freq; // TODO: Never evaluated? + uint8_t ht_support; // eval_probe_metric() + uint8_t vht_support; // eval_probe_metric() + uint32_t channel_utilization; // eval_probe_metric() + time_t time; // remove_old...entries + uint32_t station_count; // compare_station_count() <- better_ap_available() + uint8_t ssid[SSID_MAX_LEN]; // compare_sid() < -better_ap_available() char neighbor_report[NEIGHBOR_REPORT_LEN]; - uint32_t collision_domain; - uint32_t bandwidth; - uint32_t ap_weight; + uint32_t collision_domain; // TODO: ap_get_collision_count() never evaluated? + uint32_t bandwidth; // TODO: Never evaluated? + uint32_t ap_weight; // eval_probe_metric() char iface[MAX_INTERFACE_NAME]; char hostname[HOST_NAME_MAX]; } ap; @@ -232,19 +233,20 @@ typedef struct ap_s { // ---------------- Defines ---------------- #define ARRAY_AP_LEN 50 #define TIME_THRESHOLD_AP 30 + #define ARRAY_CLIENT_LEN 1000 #define TIME_THRESHOLD_CLIENT 30 #define TIME_THRESHOLD_CLIENT_UPDATE 10 #define TIME_THRESHOLD_CLIENT_KICK 60 // ---------------- Global variables ---------------- -struct ap_s ap_array[ARRAY_AP_LEN]; +extern struct ap_s ap_array[]; extern int ap_entry_last; -pthread_mutex_t ap_array_mutex; +extern pthread_mutex_t ap_array_mutex; -struct client_s client_array[ARRAY_CLIENT_LEN]; +extern struct client_s client_array[]; extern int client_entry_last; -pthread_mutex_t client_array_mutex; +extern pthread_mutex_t client_array_mutex; // ---------------- Functions ---------------- @@ -256,10 +258,14 @@ void remove_old_client_entries(time_t current_time, long long int threshold); void insert_client_to_array(client entry); -void kick_clients(uint8_t bssid[], uint32_t id); +int kick_clients(uint8_t bssid[], uint32_t id); + +void update_iw_info(uint8_t bssid[]); void client_array_insert(client entry); +client client_array_get_client(const uint8_t* client_addr); + client client_array_delete(client entry); void print_client_array(); @@ -278,20 +284,20 @@ ap ap_array_get_ap(uint8_t bssid_addr[]); int probe_array_set_all_probe_count(uint8_t client_addr[], uint32_t probe_count); +#ifndef DAWN_NO_OUTPUT int ap_get_collision_count(int col_domain); +#endif void send_beacon_reports(uint8_t bssid[], int id); /* Utils */ - -// ---------------- Defines ------------------- -#define SORT_NUM 5 - -// ---------------- Global variables ---------------- #define SORT_LENGTH 5 -char sort_string[SORT_LENGTH]; +extern char sort_string[]; // ---------------- Functions ------------------- int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], char* neighbor_report, int automatic_kick); +// All users of datastorage should call init_ / destroy_mutex at initialisation and termination respectively +int init_mutex(); +void destroy_mutex(); #endif diff --git a/src/include/dawn_iwinfo.h b/src/include/dawn_iwinfo.h index eec0a98..77150d3 100644 --- a/src/include/dawn_iwinfo.h +++ b/src/include/dawn_iwinfo.h @@ -1,12 +1,13 @@ #ifndef DAWN_RSSI_H #define DAWN_RSSI_H -#include -#include -#include -#include +#include #include +// ---------------- Global variables ---------------- +#define HOSTAPD_DIR_LEN 200 +extern char hostapd_dir_glob[]; + /** * Get RSSI using the mac adress of the client. * Function uses libiwinfo and searches through all interfaces that are existing. @@ -58,7 +59,7 @@ int get_expected_throughput(const char *ifname, uint8_t *client_addr); int get_bssid(const char *ifname, uint8_t *bssid_addr); -int get_ssid(const char *ifname, char *ssid); +int get_ssid(const char *ifname, char *ssid, size_t ssidmax); int get_channel_utilization(const char *ifname, uint64_t *last_channel_time, uint64_t *last_channel_time_busy); diff --git a/src/include/dawn_uci.h b/src/include/dawn_uci.h index 051f9d1..3324310 100644 --- a/src/include/dawn_uci.h +++ b/src/include/dawn_uci.h @@ -1,6 +1,9 @@ #ifndef DAWN_UCI_H #define DAWN_UCI_H +#include +#include + /** * Init uci. Call this function before using the other functions! * @return if call was successful. diff --git a/src/include/ieee80211_utils.h b/src/include/ieee80211_utils.h index 92e9f20..edad37e 100644 --- a/src/include/ieee80211_utils.h +++ b/src/include/ieee80211_utils.h @@ -17,4 +17,11 @@ double iee80211_calculate_bitrate(uint8_t supp_rate_val); */ double iee80211_calculate_expected_throughput_mbit(int exp_thr); +/** + * Convert 802.11k RCPI value to RSSI dB + * @param rcpi + * @return + */ +int rcpi_to_rssi(int rcpi); + #endif //DAWN_IEEE80211_UTILS_H diff --git a/src/include/mac_utils.h b/src/include/mac_utils.h new file mode 100644 index 0000000..e9b1632 --- /dev/null +++ b/src/include/mac_utils.h @@ -0,0 +1,43 @@ +#ifndef __DAWN_MAC_UTILS_H +#define __DAWN_MAC_UTILS_H + +#include + +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define STR2MAC(a) &(a)[0], &(a)[1], &(a)[2], &(a)[3], &(a)[4], &(a)[5] + +#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X" +#define MACSTRLOWER "%02x:%02x:%02x:%02x:%02x:%02x" + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +/** + * Convert mac adress string to mac adress. + * @param txt + * @param addr + * @return + */ +int hwaddr_aton(const char* txt, uint8_t* addr); + +/** + * Convert mac to use big characters. + * @param in + * @param out + * @return + */ +int convert_mac(char* in, char* out); + +/** + * Write mac to a file. + * @param path + * @param addr + */ +void write_mac_to_file(char* path, uint8_t addr[]); + +int mac_is_equal(const uint8_t addr1[], const uint8_t addr2[]); + +int mac_is_greater(const uint8_t addr1[], const uint8_t addr2[]); + +#endif diff --git a/src/include/msghandler.h b/src/include/msghandler.h new file mode 100644 index 0000000..6895a39 --- /dev/null +++ b/src/include/msghandler.h @@ -0,0 +1,47 @@ +#ifndef __DAWN_MSGHANDLER_H +#define __DAWN_MSGHANDLER_H + +#include + +#include "datastorage.h" + +/** + * Parse to probe request. + * @param msg + * @param prob_req + * @return + */ +int parse_to_probe_req(struct blob_attr* msg, probe_entry* prob_req); + +/** + * Dump a client array into the database. + * @param msg - message to parse. + * @param do_kick - use the automatic kick function when updating the clients. + * @param id - ubus id. + * @return + */ +int parse_to_clients(struct blob_attr* msg, int do_kick, uint32_t id); + +/** + * Parse to hostapd notify. + * Notify are such notifications like: + * + Disassociation + * + Deauthentication + * + ... + * @param msg + * @param notify_req + * @return + */ +int parse_to_hostapd_notify(struct blob_attr* msg, hostapd_notify_entry* notify_req); + +/** + * Handle network messages. + * @param msg + * @return + */ +int handle_network_msg(char* msg); + + +int handle_deauth_req(struct blob_attr* msg); + +#endif diff --git a/src/include/multicastsocket.h b/src/include/multicastsocket.h index dab0547..1624c21 100644 --- a/src/include/multicastsocket.h +++ b/src/include/multicastsocket.h @@ -1,6 +1,8 @@ #ifndef __DAWN_MULTICASTSTSOCKET_H #define __DAWN_MULTICASTSSOCKET_H +#include + /** * Setup a multicast socket. * Setup permissions. Join the multicast group, etc. ... diff --git a/src/include/networksocket.h b/src/include/networksocket.h index 2b26bfd..367068c 100644 --- a/src/include/networksocket.h +++ b/src/include/networksocket.h @@ -3,8 +3,6 @@ #include -pthread_mutex_t send_mutex; - /** * Init a socket using the runopts. * @param _ip - ip to use. diff --git a/src/include/tcpsocket.h b/src/include/tcpsocket.h index 1bd3670..257599f 100644 --- a/src/include/tcpsocket.h +++ b/src/include/tcpsocket.h @@ -3,7 +3,6 @@ #include #include -#include #define ARRAY_NETWORK_LEN 50 diff --git a/src/include/test_storage.h b/src/include/test_storage.h new file mode 100644 index 0000000..7aa7522 --- /dev/null +++ b/src/include/test_storage.h @@ -0,0 +1,14 @@ +#ifndef __DAWN_TESTSTORAGE_H +#define __DAWN_TESTSTORAGE_H + +#include "datastorage.h" + +/* +** Contains declerations, etc needed across datastorage and its test harness, +** but not more widely. +*/ +void ap_array_insert(ap entry); + +ap ap_array_delete(ap entry); + +#endif diff --git a/src/include/ubus.h b/src/include/ubus.h index 0bf0d6a..1de7db9 100644 --- a/src/include/ubus.h +++ b/src/include/ubus.h @@ -4,7 +4,6 @@ #include #include - #include "datastorage.h" // 802.11 Status codes @@ -17,9 +16,6 @@ #define UNSPECIFIED_REASON 0 #define NO_MORE_STAS 5 -#define HOSTAPD_DIR_LEN 200 -char hostapd_dir_glob[HOSTAPD_DIR_LEN]; - /** * Init ubus. * Setup tcp socket. @@ -41,14 +37,6 @@ void start_umdns_update(); */ int ubus_call_umdns(); -/** - * Parse to probe request. - * @param msg - * @param prob_req - * @return - */ -int parse_to_probe_req(struct blob_attr *msg, probe_entry *prob_req); - /** * Parse to authentication request. * @param msg @@ -65,27 +53,6 @@ int parse_to_auth_req(struct blob_attr *msg, auth_entry *auth_req); */ int parse_to_assoc_req(struct blob_attr *msg, assoc_entry *assoc_req); -/** - * Dump a client array into the database. - * @param msg - message to parse. - * @param do_kick - use the automatic kick function when updating the clients. - * @param id - ubus id. - * @return - */ -int parse_to_clients(struct blob_attr *msg, int do_kick, uint32_t id); - -/** - * Parse to hostapd notify. - * Notify are such notifications like: - * + Disassociation - * + Deauthentication - * + ... - * @param msg - * @param notify_req - * @return - */ -int parse_to_hostapd_notify(struct blob_attr *msg, hostapd_notify_entry *notify_req); - /** * Kick client from all hostapd interfaces. * @param client_addr - the client adress of the client to kick. @@ -102,19 +69,34 @@ void del_client_all_interfaces(const uint8_t *client_addr, uint32_t reason, uint void update_hostapd_sockets(struct uloop_timeout *t); /** - * Handle network messages. - * @param msg + * Send control message to all hosts to add the mac to a don't control list. + * @param client_addr * @return */ -int handle_network_msg(char *msg); +int send_add_mac(uint8_t *client_addr); + +void ubus_send_beacon_report(uint8_t client[], int id); + +void uloop_add_data_cbs(); + +int uci_send_via_network(); + +int build_hearing_map_sort_client(struct blob_buf* b); + +int build_network_overview(struct blob_buf* b); + +int ap_get_nr(struct blob_buf* b, uint8_t own_bssid_addr[]); + +int parse_add_mac_to_file(struct blob_attr* msg); + +int handle_auth_req(struct blob_attr* msg); /** - * Send message via network. - * @param msg - * @param method + * Send probe message via the network. + * @param probe_entry * @return */ -int send_blob_attr_via_network(struct blob_attr *msg, char *method); +int ubus_send_probe_via_network(struct probe_entry_s probe_entry); /** * Add mac to a list that contains addresses of clients that can not be controlled. @@ -125,18 +107,45 @@ int send_blob_attr_via_network(struct blob_attr *msg, char *method); void blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const uint8_t *addr); /** - * Send control message to all hosts to add the mac to a don't control list. + * Send message via network. + * @param msg + * @param method + * @return + */ +int send_blob_attr_via_network(struct blob_attr* msg, char* method); + +/** + * Set client timer for updating the clients. + * @param time + */ +void add_client_update_timer(time_t time); + +/** + * Kick client from hostapd interface. + * @param id - the ubus id. + * @param client_addr - the client adress of the client to kick. + * @param reason - the reason to kick the client. + * @param deauth - if the client should be deauthenticated. + * @param ban_time - the ban time the client is not allowed to connect again. + */ +void del_client_interface(uint32_t id, const uint8_t* client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time); + +/** + * Function to set the probe counter to the min probe request. + * This allows that the client is able to connect directly without sending multiple probe requests to the Access Point. * @param client_addr * @return */ -int send_add_mac(uint8_t *client_addr); +int send_set_probe(uint8_t client_addr[]); -int uci_send_via_network(); - -int build_hearing_map_sort_client(struct blob_buf *b); - -int build_network_overview(struct blob_buf *b); - -int ap_get_nr(struct blob_buf *b, uint8_t own_bssid_addr[]); +/** + * Function to tell a client that it is about to be disconnected. + * @param id + * @param client_addr + * @param dest_ap + * @param duration + * @return - 0 = asynchronous (client has been told to remove itself, and caller should manage arrays); 1 = synchronous (caller should assume arrays are updated) + */ +int wnm_disassoc_imminent(uint32_t id, const uint8_t* client_addr, char* dest_ap, uint32_t duration); #endif diff --git a/src/include/uface.h b/src/include/uface.h deleted file mode 100644 index ae3a6bd..0000000 --- a/src/include/uface.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __DAWN_UFACE_H -#define __DAWN_UFACE_H - -/** - * Set client timer for updating the clients. - * @param time - */ -void add_client_update_timer(time_t time); - -/** - * Kick client from hostapd interface. - * @param id - the ubus id. - * @param client_addr - the client adress of the client to kick. - * @param reason - the reason to kick the client. - * @param deauth - if the client should be deauthenticated. - * @param ban_time - the ban time the client is not allowed to connect again. - */ -void del_client_interface(uint32_t id, const uint8_t *client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time); - -/** - * Function to set the probe counter to the min probe request. - * This allows that the client is able to connect directly without sending multiple probe requests to the Access Point. - * @param client_addr - * @return - */ -int send_set_probe(uint8_t client_addr[]); - -void ubus_send_beacon_report(uint8_t client[], int id); - -/** - * Send probe message via the network. - * @param probe_entry - * @return - */ -int ubus_send_probe_via_network(struct probe_entry_s probe_entry); - -void uloop_add_data_cbs(); - -void wnm_disassoc_imminent(uint32_t id, const uint8_t *client_addr, char* dest_ap, uint32_t duration); - -#endif // __DAWN_UFACE_H diff --git a/src/include/utils.h b/src/include/utils.h index 2a54b19..11a5dc7 100644 --- a/src/include/utils.h +++ b/src/include/utils.h @@ -2,43 +2,13 @@ #define __DAWN_UTILS_H #include -#include - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define STR2MAC(a) &(a)[0], &(a)[1], &(a)[2], &(a)[3], &(a)[4], &(a)[5] - -#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X" -#define MACSTRLOWER "%02x:%02x:%02x:%02x:%02x:%02x" /** * Convert char to binary. * @param ch * @return */ -int hex_to_bin(char ch); - -/** - * Convert mac adress string to mac adress. - * @param txt - * @param addr - * @return - */ -int hwaddr_aton(const char *txt, uint8_t *addr); - -/** - * Convert mac to use big characters. - * @param in - * @param out - * @return - */ -int convert_mac(char *in, char *out); - -/** - * Write mac to a file. - * @param path - * @param addr - */ -void write_mac_to_file(char *path, uint8_t addr[]); +int hex_to_dec(char ch); /** * Check if a string is greater than another one. @@ -48,6 +18,4 @@ void write_mac_to_file(char *path, uint8_t addr[]); */ int string_is_greater(uint8_t *str, uint8_t *str_2); -int rcpi_to_rssi(int rcpi); - #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index ee17b77..1319f59 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,7 @@ #include "networksocket.h" #include "ubus.h" #include "dawn_uci.h" +#include "dawn_iwinfo.h" #include "tcpsocket.h" #include "crypto.h" @@ -15,8 +16,6 @@ void daemon_shutdown(); void signal_handler(int sig); -int init_mutex(); - struct sigaction signal_action; void daemon_shutdown() { @@ -25,11 +24,7 @@ void daemon_shutdown() { uci_clear(); uloop_cancelled = true; - // free resources - fprintf(stdout, "Freeing mutex resources\n"); - pthread_mutex_destroy(&probe_array_mutex); - pthread_mutex_destroy(&client_array_mutex); - pthread_mutex_destroy(&ap_array_mutex); + destroy_mutex(); } void signal_handler(int sig) { @@ -49,30 +44,6 @@ void signal_handler(int sig) { } } -int init_mutex() { - - if (pthread_mutex_init(&probe_array_mutex, NULL) != 0) { - fprintf(stderr, "Mutex init failed!\n"); - return 1; - } - - if (pthread_mutex_init(&client_array_mutex, NULL) != 0) { - fprintf(stderr, "Mutex init failed!\n"); - return 1; - } - - if (pthread_mutex_init(&ap_array_mutex, NULL) != 0) { - fprintf(stderr, "Mutex init failed!\n"); - return 1; - } - - if (pthread_mutex_init(&denied_array_mutex, NULL) != 0) { - fprintf(stderr, "Mutex init failed!\n"); - return 1; - } - return 0; -} - int main(int argc, char **argv) { const char *ubus_socket = NULL; @@ -89,6 +60,7 @@ int main(int argc, char **argv) { sigaction(SIGINT, &signal_action, NULL); uci_init(); + // TODO: Why the extra loacl struct to retuen into? struct network_config_s net_config = uci_get_dawn_network(); network_config = net_config; @@ -96,6 +68,7 @@ int main(int argc, char **argv) { gcrypt_init(); gcrypt_set_key_and_iv(net_config.shared_key, net_config.iv); + // TODO: Why the extra loacl struct to retuen into? struct time_config_s time_config = uci_get_time_config(); timeout_config = time_config; // TODO: Refactor... diff --git a/src/network/broadcastsocket.c b/src/network/broadcastsocket.c index b6eec18..c857da7 100644 --- a/src/network/broadcastsocket.c +++ b/src/network/broadcastsocket.c @@ -1,11 +1,7 @@ -#include #include -#include #include -#include #include -#include "networksocket.h" #include "broadcastsocket.h" int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_port, struct sockaddr_in *addr) { diff --git a/src/network/multicastsocket.c b/src/network/multicastsocket.c index 4d87fcb..a4678c3 100644 --- a/src/network/multicastsocket.c +++ b/src/network/multicastsocket.c @@ -1,13 +1,6 @@ #include -#include -#include -#include -#include -#include #include -#include #include -#include #include "multicastsocket.h" diff --git a/src/network/networksocket.c b/src/network/networksocket.c index cf22f02..8a25ca7 100644 --- a/src/network/networksocket.c +++ b/src/network/networksocket.c @@ -1,28 +1,29 @@ -#include #include #include #include -#include #include -#include "networksocket.h" -#include "datastorage.h" #include "multicastsocket.h" #include "broadcastsocket.h" -#include "ubus.h" +#include "msghandler.h" #include "crypto.h" +#include "datastorage.h" +#include "networksocket.h" + /* Network Defines */ #define MAX_RECV_STRING 2048 /* Network Attributes */ -int sock; -struct sockaddr_in addr; -const char *ip; -unsigned short port; -char recv_string[MAX_RECV_STRING + 1]; -int recv_string_len; -int multicast_socket; +static int sock; +static struct sockaddr_in addr; +static const char *ip; +static unsigned short port; +static char recv_string[MAX_RECV_STRING + 1]; +static int recv_string_len; +static int multicast_socket; + +static pthread_mutex_t send_mutex; void *receive_msg(void *args); @@ -102,7 +103,7 @@ void *receive_msg_enc(void *args) { if (!base64_dec_str){ fprintf(stderr, "Received network error: not enought memory\n"); return 0; - } + } int base64_dec_length = b64_decode(recv_string, base64_dec_str, B64_DECODE_LEN(strlen(recv_string))); char *dec = gcrypt_decrypt_msg(base64_dec_str, base64_dec_length); if (!dec){ @@ -147,7 +148,7 @@ int send_string_enc(char *msg) { fprintf(stderr, "sendto() error: not enought memory\n"); pthread_mutex_unlock(&send_mutex); exit(EXIT_FAILURE); - } + } char *base64_enc_str = malloc(B64_ENCODE_LEN(length_enc)); if (!base64_enc_str){ @@ -155,7 +156,7 @@ int send_string_enc(char *msg) { fprintf(stderr, "sendto() error: not enought memory\n"); pthread_mutex_unlock(&send_mutex); exit(EXIT_FAILURE); - } + } size_t base64_enc_length = b64_encode(enc, length_enc, base64_enc_str, B64_ENCODE_LEN(length_enc)); if (sendto(sock, diff --git a/src/network/tcpsocket.c b/src/network/tcpsocket.c index 58b6ded..bf62368 100644 --- a/src/network/tcpsocket.c +++ b/src/network/tcpsocket.c @@ -1,15 +1,14 @@ #include -#include -#include -#include // base64 encoding -#include -#include -#include -#include -#include "tcpsocket.h" #include -#include "ubus.h" +#include + +#include "msghandler.h" #include "crypto.h" +#include "datastorage.h" +#include "tcpsocket.h" + +#define STR_EVAL(x) #x +#define STR_QUOTE(x) STR_EVAL(x) LIST_HEAD(tcp_sock_list); @@ -82,39 +81,43 @@ static void client_to_server_state(struct ustream *s) { static void client_read_cb(struct ustream *s, int bytes) { char *str, *str_tmp; int len = 0; - uint32_t final_len = sizeof(uint32_t); + uint32_t final_len = sizeof(uint32_t); // big enough to get msg length str = malloc(final_len); if (!str) { - fprintf(stderr,"not enough memory\n"); + fprintf(stderr,"not enough memory (" STR_QUOTE(__LINE__) ")\n"); goto nofree; } - + if ((len = ustream_pending_data(s, false)) < final_len){//ensure recv sizeof(uint32_t). fprintf(stdout,"not complete msg, len:%d, expected len:%u\n", len, final_len); goto out; } - ustream_read(s, str, final_len); - - final_len = ntohl(*(uint32_t *)str) - sizeof(uint32_t);//the final_len in headder includes header itself + if (ustream_read(s, str, final_len) != final_len) // read msg length bytes + { + fprintf(stdout,"msg length read failed\n"); + goto out; + } + + final_len = ntohl(*(uint32_t *)str) - final_len;//the final_len in headder includes header itself str_tmp = realloc(str, final_len); if (!str_tmp) { - fprintf(stderr,"not enough memory\n"); - goto out;//On failure, realloc returns a null pointer. The original pointer str remains valid + fprintf(stderr,"not enough memory (%" PRIu32 " @ " STR_QUOTE(__LINE__) ")\n", final_len); + goto out;//On failure, realloc returns a null pointer. The original pointer str remains valid //and may need to be deallocated with free() or realloc(). } str = str_tmp; - + if ((len = ustream_pending_data(s, false)) < final_len){//ensure recv final_len bytes. fprintf(stdout,"not complete msg, len:%d, expected len:%u\n", len, final_len); goto out; } ustream_read(s, str, final_len); - if (network_config.use_symm_enc) { - char *dec = gcrypt_decrypt_msg(str, final_len);//len of str is final_len + if (network_config.use_symm_enc) { + char *dec = gcrypt_decrypt_msg(str, final_len);//len of str is final_len if (!dec) { - fprintf(stderr,"not enough memory\n"); + fprintf(stderr,"not enough memory (" STR_QUOTE(__LINE__) ")\n"); goto out; - } + } handle_network_msg(dec); free(dec); } else { @@ -247,17 +250,17 @@ void send_tcp(char *msg) { size_t msglen = strlen(msg)+1; char *enc = gcrypt_encrypt_msg(msg, msglen, &length_enc); if (!enc){ - fprintf(stderr, "Ustream error: not enought memory\n"); + fprintf(stderr, "Ustream error: not enought memory (" STR_QUOTE(__LINE__) ")\n"); return; - } + } uint32_t final_len = length_enc + sizeof(final_len); char *final_str = malloc(final_len); if (!final_str){ free(enc); - fprintf(stderr, "Ustream error: not enought memory\n"); + fprintf(stderr, "Ustream error: not enought memory (" STR_QUOTE(__LINE__) ")\n"); return; - } + } uint32_t *msg_header = (uint32_t *)final_str; *msg_header = htonl(final_len); memcpy(final_str+sizeof(final_len), enc, length_enc); @@ -267,14 +270,14 @@ void send_tcp(char *msg) { int len_ustream = ustream_write(&con->stream.stream, final_str, final_len, 0); printf("Ustream send: %d\n", len_ustream); if (len_ustream <= 0) { - fprintf(stderr,"Ustream error!\n"); + fprintf(stderr,"Ustream error(" STR_QUOTE(__LINE__) ")!\n"); //ERROR HANDLING! if (con->stream.stream.write_error) { ustream_free(&con->stream.stream); close(con->fd.fd); list_del(&con->list); free(con); - } + } } } @@ -287,9 +290,9 @@ void send_tcp(char *msg) { uint32_t final_len = msglen + sizeof(final_len); char *final_str = malloc(final_len); if (!final_str){ - fprintf(stderr, "Ustream error: not enought memory\n"); + fprintf(stderr, "Ustream error: not enought memory (" STR_QUOTE(__LINE__) ")\n"); return; - } + } uint32_t *msg_header = (uint32_t *)final_str; *msg_header = htonl(final_len); memcpy(final_str+sizeof(final_len), msg, msglen); @@ -301,13 +304,13 @@ void send_tcp(char *msg) { printf("Ustream send: %d\n", len_ustream); if (len_ustream <= 0) { //ERROR HANDLING! - fprintf(stderr,"Ustream error!\n"); + fprintf(stderr,"Ustream error(" STR_QUOTE(__LINE__) ")!\n"); if (con->stream.stream.write_error) { ustream_free(&con->stream.stream); close(con->fd.fd); list_del(&con->list); free(con); - } + } } } } diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index 41321b8..a35cfea 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -1,11 +1,20 @@ #include #include "dawn_iwinfo.h" -#include "utils.h" +#include "dawn_uci.h" +#include "mac_utils.h" #include "ieee80211_utils.h" #include "datastorage.h" -#include "uface.h" +#include "test_storage.h" +#include "msghandler.h" +#include "ubus.h" + +struct probe_metric_s dawn_metric; +struct network_config_s network_config; +struct time_config_s timeout_config; + + #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] @@ -16,45 +25,62 @@ #define WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE BIT(5) #define WLAN_RRM_CAPS_BEACON_REPORT_TABLE BIT(6) -int go_next_help(char sort_order[], int i, probe_entry entry, +static int go_next_help(char sort_order[], int i, probe_entry entry, probe_entry next_entry); -int go_next(char sort_order[], int i, probe_entry entry, +static int go_next(char sort_order[], int i, probe_entry entry, probe_entry next_entry); -int client_array_go_next(char sort_order[], int i, client entry, +static int client_array_go_next(char sort_order[], int i, client entry, client next_entry); -int client_array_go_next_help(char sort_order[], int i, client entry, +static int client_array_go_next_help(char sort_order[], int i, client entry, client next_entry); -int kick_client(struct client_s client_entry, char* neighbor_report); +static int kick_client(struct client_s client_entry, char* neighbor_report); -void ap_array_insert(ap entry); +static void print_ap_entry(ap entry); -ap ap_array_delete(ap entry); +static int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]); -void print_ap_entry(ap entry); - -int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]); - -int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare, uint8_t *client_addr, +static int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare, uint8_t *client_addr, int automatic_kick); -int compare_ssid(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare); +static int compare_ssid(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare); -int denied_req_array_go_next(char sort_order[], int i, auth_entry entry, +static int denied_req_array_go_next(char sort_order[], int i, auth_entry entry, auth_entry next_entry); -int denied_req_array_go_next_help(char sort_order[], int i, auth_entry entry, +static int denied_req_array_go_next_help(char sort_order[], int i, auth_entry entry, auth_entry next_entry); +// ---------------- Global variables ---------------- +struct auth_entry_s denied_req_array[DENY_REQ_ARRAY_LEN]; +extern int denied_req_last; +pthread_mutex_t denied_array_mutex; + +struct probe_entry_s probe_array[PROBE_ARRAY_LEN]; +extern int probe_entry_last; +pthread_mutex_t probe_array_mutex; + +struct ap_s ap_array[ARRAY_AP_LEN]; +extern int ap_entry_last; +pthread_mutex_t ap_array_mutex; + +struct client_s client_array[ARRAY_CLIENT_LEN]; +extern int client_entry_last; +pthread_mutex_t client_array_mutex; + +char sort_string[SORT_LENGTH]; + int probe_entry_last = -1; int client_entry_last = -1; int ap_entry_last = -1; int mac_list_entry_last = -1; int denied_req_last = -1; +uint8_t mac_list[MAC_LIST_LENGTH][ETH_ALEN]; + void send_beacon_reports(uint8_t bssid[], int id) { pthread_mutex_lock(&client_array_mutex); @@ -72,9 +98,9 @@ void send_beacon_reports(uint8_t bssid[], int id) { if (!mac_is_equal(client_array[j].bssid_addr, bssid)) { break; } - if (client_array[j].rrm_enabled_capa & + if (client_array[j].rrm_enabled_capa & (WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE | - WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | + WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | WLAN_RRM_CAPS_BEACON_REPORT_TABLE)) ubus_send_beacon_report(client_array[j].client_addr, id); } @@ -92,14 +118,14 @@ int eval_probe_metric(struct probe_entry_s probe_entry) { // check if ap entry is available if (mac_is_equal(ap_entry.bssid_addr, probe_entry.bssid_addr)) { score += probe_entry.ht_capabilities && ap_entry.ht_support ? dawn_metric.ht_support : 0; - score += !probe_entry.ht_capabilities && !ap_entry.ht_support ? dawn_metric.no_ht_support : 0; + score += !probe_entry.ht_capabilities && !ap_entry.ht_support ? dawn_metric.no_ht_support : 0; // TODO: Is both devices not having a capability worthy of scoring? // performance anomaly? if (network_config.bandwidth >= 1000 || network_config.bandwidth == -1) { score += probe_entry.vht_capabilities && ap_entry.vht_support ? dawn_metric.vht_support : 0; } - score += !probe_entry.vht_capabilities && !ap_entry.vht_support ? dawn_metric.no_vht_support : 0; + score += !probe_entry.vht_capabilities && !ap_entry.vht_support ? dawn_metric.no_vht_support : 0; // TODO: Is both devices not having a capability worthy of scoring? score += ap_entry.channel_utilization <= dawn_metric.chan_util_val ? dawn_metric.chan_util : 0; score += ap_entry.channel_utilization > dawn_metric.max_chan_util_val ? dawn_metric.max_chan_util : 0; @@ -107,9 +133,15 @@ int eval_probe_metric(struct probe_entry_s probe_entry) { } score += (probe_entry.freq > 5000) ? dawn_metric.freq : 0; + + // TODO: Should RCPI be used here as well? + // TODO: Check higher value means more signal, not more -dB :) + // TODO: Should this be more scaled? Should -63dB on current and -77dB on other both score 0 if low / high are -80db and -60dB? + // TODO: That then lets device capabilites dominate score - making them more important than RSSI difference of 14dB. score += (probe_entry.signal >= dawn_metric.rssi_val) ? dawn_metric.rssi : 0; score += (probe_entry.signal <= dawn_metric.low_rssi_val) ? dawn_metric.low_rssi : 0; + // TODO: This magic value never checked by caller. What does it achieve? if (score < 0) score = -2; // -1 already used... @@ -119,7 +151,7 @@ int eval_probe_metric(struct probe_entry_s probe_entry) { return score; } -int compare_ssid(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare) { +static int compare_ssid(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare) { ap ap_entry_own = ap_array_get_ap(bssid_addr_own); ap ap_entry_to_compre = ap_array_get_ap(bssid_addr_to_compare); @@ -130,7 +162,7 @@ int compare_ssid(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare) { return 0; } -int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare, uint8_t *client_addr, +static int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare, uint8_t *client_addr, int automatic_kick) { ap ap_entry_own = ap_array_get_ap(bssid_addr_own); @@ -185,7 +217,7 @@ int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], char* neigh } if (mac_is_equal(bssid_addr, probe_array[j].bssid_addr)) { printf("Calculating own score!\n"); - own_score = eval_probe_metric(probe_array[j]); + own_score = eval_probe_metric(probe_array[j]); //TODO: Should the -2 return be handled? break; } } @@ -196,7 +228,7 @@ int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], char* neigh } int k; - int max_score = 0; + int max_score = 0; //TODO: Set this to own_score so we are just looking for AP that are better? int kick = 0; for (k = i; k <= probe_entry_last; k++) { int score_to_compare; @@ -241,6 +273,8 @@ int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], char* neigh //return 1; } + // TODO: Not sure this is correct. Isn't it always checking against current AP, but should be using + // TODO: previous max_score AP and new candidate? Also is absolute number meaningful when AP have diffeent capacity? if (dawn_metric.use_station_count > 0 && own_score == score_to_compare && score_to_compare > max_score) { // only compare if score is bigger or equal 0 @@ -270,14 +304,19 @@ int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], char* neigh return kick; } -int kick_client(struct client_s client_entry, char* neighbor_report) { +// TODO: mac_in_maclist() returns 0 or 1; better_ap_available() returns -1, 0, or 1. +// What is the intended behaviour for 1 && -1 -> 1? Is this relying on undocumented side-effects to get -1? +static int kick_client(struct client_s client_entry, char* neighbor_report) { return !mac_in_maclist(client_entry.client_addr) && better_ap_available(client_entry.bssid_addr, client_entry.client_addr, neighbor_report, 1); } -void kick_clients(uint8_t bssid[], uint32_t id) { +int kick_clients(uint8_t bssid[], uint32_t id) { pthread_mutex_lock(&client_array_mutex); pthread_mutex_lock(&probe_array_mutex); + + int kicked_clients = 0; + printf("-------- KICKING CLIENTS!!!---------\n"); char mac_buf_ap[20]; sprintf(mac_buf_ap, MACSTR, MAC2STR(bssid)); @@ -291,6 +330,130 @@ void kick_clients(uint8_t bssid[], uint32_t id) { } } + // Go threw clients + int j = i; + while (j <= client_entry_last) { + if (!mac_is_equal(client_array[j].bssid_addr, bssid)) { + break; + } + + char neighbor_report[NEIGHBOR_REPORT_LEN] = ""; + strcpy(neighbor_report, "This is a test"); + int do_kick = kick_client(client_array[j], neighbor_report); + printf("Chosen AP %s\n", neighbor_report); + + // better ap available + if (do_kick > 0) { + + // kick after algorithm decided to kick several times + // + rssi is changing a lot + // + chan util is changing a lot + // + ping pong behavior of clients will be reduced + client_array[j].kick_count++; + printf("Comparing kick count! kickcount: %d to min_kick_count: %d!\n", client_array[j].kick_count, + dawn_metric.min_kick_count); + if (client_array[j].kick_count < dawn_metric.min_kick_count) { + j++; + } + else + { + printf("Better AP available. Kicking client:\n"); + print_client_entry(client_array[j]); + printf("Check if client is active receiving!\n"); + + float rx_rate, tx_rate; + if (get_bandwidth_iwinfo(client_array[j].client_addr, &rx_rate, &tx_rate)) { + printf("No active transmission data for client. Don't kick!\n"); + + j++; + } + else + { + // only use rx_rate for indicating if transmission is going on + // <= 6MBits <- probably no transmission + // tx_rate has always some weird value so don't use ist + if (rx_rate > dawn_metric.bandwidth_threshold) { + printf("Client is probably in active transmisison. Don't kick! RxRate is: %f\n", rx_rate); + + j++; + } + else + { + printf("Client is probably NOT in active transmisison. KICK! RxRate is: %f\n", rx_rate); + + // here we should send a messsage to set the probe.count for all aps to the min that there is no delay between switching + // the hearing map is full... + send_set_probe(client_array[j].client_addr); + + // don't deauth station? <- deauth is better! + // maybe we can use handovers... + //del_client_interface(id, client_array[j].client_addr, NO_MORE_STAS, 1, 1000); + int sync_kick = wnm_disassoc_imminent(id, client_array[j].client_addr, neighbor_report, 12); + + // Synchronous kick is a test harness feature to indicate arrays have been updated, so don't change further + if (sync_kick) + { + kicked_clients++; + } + else + { + client_array_delete(client_array[j]); + + // don't delete clients in a row. use update function again... + // -> chan_util update, ... + add_client_update_timer(timeout_config.update_client * 1000 / 4); + break; + } + } + } + } + } + // no entry in probe array for own bssid + // TODO: Is test against -1 from (1 && -1) portable? + else if (do_kick == -1) { + printf("No Information about client. Force reconnect:\n"); + print_client_entry(client_array[j]); + del_client_interface(id, client_array[j].client_addr, 0, 1, 0); + + + j++; + } + // ap is best + else { + printf("AP is best. Client will stay:\n"); + print_client_entry(client_array[j]); + // set kick counter to 0 again + client_array[j].kick_count = 0; + + j++; + } + } + + printf("---------------------------\n"); + + pthread_mutex_unlock(&probe_array_mutex); + pthread_mutex_unlock(&client_array_mutex); + + return kicked_clients; +} + +void update_iw_info(uint8_t bssid[]) { + pthread_mutex_lock(&client_array_mutex); + pthread_mutex_lock(&probe_array_mutex); + + printf("-------- IW INFO UPDATE!!!---------\n"); + char mac_buf_ap[20]; + sprintf(mac_buf_ap, MACSTR, MAC2STR(bssid)); + printf("EVAL %s\n", mac_buf_ap); + + // Seach for BSSID + int i; + for (i = 0; i <= client_entry_last; i++) { + if (mac_is_equal(client_array[i].bssid_addr, bssid)) { + break; + } + } + // Go threw clients int j; for (j = i; j <= client_entry_last; j++) { @@ -308,75 +471,13 @@ void kick_clients(uint8_t bssid[], uint32_t id) { pthread_mutex_unlock(&probe_array_mutex); if (!probe_array_update_rssi(client_array[j].bssid_addr, client_array[j].client_addr, rssi, true)) { printf("Failed to update rssi!\n"); - } else { + } + else { printf("Updated rssi: %d\n", rssi); } pthread_mutex_lock(&probe_array_mutex); } - char neighbor_report[NEIGHBOR_REPORT_LEN] = ""; - int do_kick = kick_client(client_array[j], neighbor_report); - printf("Chosen AP %s\n",neighbor_report); - - // better ap available - if (do_kick > 0) { - - // kick after algorithm decided to kick several times - // + rssi is changing a lot - // + chan util is changing a lot - // + ping pong behavior of clients will be reduced - client_array[j].kick_count++; - printf("Comparing kick count! kickcount: %d to min_kick_count: %d!\n", client_array[j].kick_count, - dawn_metric.min_kick_count); - if (client_array[j].kick_count < dawn_metric.min_kick_count) { - continue; - } - - printf("Better AP available. Kicking client:\n"); - print_client_entry(client_array[j]); - printf("Check if client is active receiving!\n"); - - float rx_rate, tx_rate; - if (get_bandwidth_iwinfo(client_array[j].client_addr, &rx_rate, &tx_rate)) { - // only use rx_rate for indicating if transmission is going on - // <= 6MBits <- probably no transmission - // tx_rate has always some weird value so don't use ist - if (rx_rate > dawn_metric.bandwidth_threshold) { - printf("Client is probably in active transmisison. Don't kick! RxRate is: %f\n", rx_rate); - continue; - } - } - printf("Client is probably NOT in active transmisison. KICK! RxRate is: %f\n", rx_rate); - - - // here we should send a messsage to set the probe.count for all aps to the min that there is no delay between switching - // the hearing map is full... - send_set_probe(client_array[j].client_addr); - - // don't deauth station? <- deauth is better! - // maybe we can use handovers... - //del_client_interface(id, client_array[j].client_addr, NO_MORE_STAS, 1, 1000); - wnm_disassoc_imminent(id, client_array[j].client_addr, neighbor_report, 12); - client_array_delete(client_array[j]); - - // don't delete clients in a row. use update function again... - // -> chan_util update, ... - add_client_update_timer(timeout_config.update_client * 1000 / 4); - break; - - // no entry in probe array for own bssid - } else if (do_kick == -1) { - printf("No Information about client. Force reconnect:\n"); - print_client_entry(client_array[j]); - del_client_interface(id, client_array[j].client_addr, 0, 1, 0); - - // ap is best - } else { - printf("AP is best. Client will stay:\n"); - print_client_entry(client_array[j]); - // set kick counter to 0 again - client_array[j].kick_count = 0; - } } printf("---------------------------\n"); @@ -402,7 +503,7 @@ int is_connected_somehwere(uint8_t client_addr[]) { return found_in_array; } -int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]) { +static int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]) { int i; int found_in_array = 0; @@ -421,7 +522,7 @@ int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]) { return found_in_array; } -int client_array_go_next_help(char sort_order[], int i, client entry, +static int client_array_go_next_help(char sort_order[], int i, client entry, client next_entry) { switch (sort_order[i]) { // bssid-mac @@ -437,7 +538,7 @@ int client_array_go_next_help(char sort_order[], int i, client entry, return 0; } -int client_array_go_next(char sort_order[], int i, client entry, +static int client_array_go_next(char sort_order[], int i, client entry, client next_entry) { int conditions = 1; for (int j = 0; j < i; j++) { @@ -471,6 +572,26 @@ void client_array_insert(client entry) { } } +client client_array_get_client(const uint8_t* client_addr) { + if (client_entry_last == -1) { + client nc = { .client_addr = {0, 0, 0, 0, 0, 0} }; + + return nc; + } + + //pthread_mutex_lock(&client_array_mutex); + int i; + + for (i = 0; i <= client_entry_last; i++) { + if (mac_is_equal(client_addr, client_array[i].client_addr)) { + break; + } + } + //pthread_mutex_unlock(&client_array_mutex); + + return client_array[i]; +} + client client_array_delete(client entry) { int i; @@ -482,7 +603,7 @@ client client_array_delete(client entry) { } for (i = 0; i <= client_entry_last; i++) { - if (mac_is_equal(entry.bssid_addr, client_array[i].bssid_addr) && + if (mac_is_equal(entry.bssid_addr, client_array[i].bssid_addr) && // TODO: Why check BSSID here? Aren't entries unique by client MAC? mac_is_equal(entry.client_addr, client_array[i].client_addr)) { found_in_array = 1; tmp = client_array[i]; @@ -510,7 +631,7 @@ void probe_array_insert(probe_entry entry) { int i; for (i = 0; i <= probe_entry_last; i++) { - if (!go_next(sort_string, SORT_NUM, entry, probe_array[i])) { + if (!go_next(sort_string, SORT_LENGTH, entry, probe_array[i])) { break; } } @@ -668,7 +789,6 @@ void print_probe_array() { probe_entry insert_to_array(probe_entry entry, int inc_counter, int save_80211k, int is_beacon) { pthread_mutex_lock(&probe_array_mutex); - entry.time = time(0); entry.counter = 0; probe_entry tmp = probe_array_delete(entry); @@ -700,7 +820,6 @@ probe_entry insert_to_array(probe_entry entry, int inc_counter, int save_80211k, ap insert_to_ap_array(ap entry) { pthread_mutex_lock(&ap_array_mutex); - entry.time = time(0); ap_array_delete(entry); ap_array_insert(entry); pthread_mutex_unlock(&ap_array_mutex); @@ -709,6 +828,7 @@ ap insert_to_ap_array(ap entry) { } +// TODO: What is collision domain used for? int ap_get_collision_count(int col_domain) { int ret_sta_count = 0; @@ -806,33 +926,43 @@ ap ap_array_delete(ap entry) { } void remove_old_client_entries(time_t current_time, long long int threshold) { - for (int i = 0; i <= client_entry_last; i++) { + int i = 0; + while (i <= client_entry_last) { if (client_array[i].time < current_time - threshold) { client_array_delete(client_array[i]); } + else { + i++; + } } } void remove_old_probe_entries(time_t current_time, long long int threshold) { - for (int i = 0; i <= probe_entry_last; i++) { - if (probe_array[i].time < current_time - threshold) { - if (!is_connected(probe_array[i].bssid_addr, probe_array[i].client_addr)) - probe_array_delete(probe_array[i]); + int i = 0; + while (i <= probe_entry_last) { + if ((probe_array[i].time < current_time - threshold) && !is_connected(probe_array[i].bssid_addr, probe_array[i].client_addr)) { + probe_array_delete(probe_array[i]); + } + else { + i++; } } } void remove_old_ap_entries(time_t current_time, long long int threshold) { - for (int i = 0; i <= ap_entry_last; i++) { + int i = 0; + while (i <= ap_entry_last) { if (ap_array[i].time < current_time - threshold) { ap_array_delete(ap_array[i]); } + else { + i++; + } } } void insert_client_to_array(client entry) { pthread_mutex_lock(&client_array_mutex); - entry.time = time(0); entry.kick_count = 0; client client_tmp = client_array_delete(entry); @@ -883,6 +1013,8 @@ void insert_macs_from_file() { //exit(EXIT_SUCCESS); } + +// TODO: This list only ever seems to get longer. WHy do we need it? int insert_to_maclist(uint8_t mac[]) { if (mac_in_maclist(mac)) { return -1; @@ -909,7 +1041,6 @@ int mac_in_maclist(uint8_t mac[]) { auth_entry insert_to_denied_req_array(auth_entry entry, int inc_counter) { pthread_mutex_lock(&denied_array_mutex); - entry.time = time(0); entry.counter = 0; auth_entry tmp = denied_req_array_delete(entry); @@ -930,7 +1061,7 @@ auth_entry insert_to_denied_req_array(auth_entry entry, int inc_counter) { return entry; } -int denied_req_array_go_next_help(char sort_order[], int i, auth_entry entry, +static int denied_req_array_go_next_help(char sort_order[], int i, auth_entry entry, auth_entry next_entry) { switch (sort_order[i]) { // bssid-mac @@ -946,7 +1077,7 @@ int denied_req_array_go_next_help(char sort_order[], int i, auth_entry entry, return 0; } -int denied_req_array_go_next(char sort_order[], int i, auth_entry entry, +static int denied_req_array_go_next(char sort_order[], int i, auth_entry entry, auth_entry next_entry) { int conditions = 1; for (int j = 0; j < i; j++) { @@ -1009,7 +1140,7 @@ auth_entry denied_req_array_delete(auth_entry entry) { return tmp; } -int go_next_help(char sort_order[], int i, probe_entry entry, +static int go_next_help(char sort_order[], int i, probe_entry entry, probe_entry next_entry) { switch (sort_order[i]) { // bssid-mac @@ -1045,7 +1176,7 @@ int go_next_help(char sort_order[], int i, probe_entry entry, } } -int go_next(char sort_order[], int i, probe_entry entry, +static int go_next(char sort_order[], int i, probe_entry entry, probe_entry next_entry) { int conditions = 1; for (int j = 0; j < i; j++) { @@ -1054,25 +1185,9 @@ int go_next(char sort_order[], int i, probe_entry entry, return conditions && go_next_help(sort_order, i, entry, next_entry); } -int mac_is_equal(uint8_t addr1[], uint8_t addr2[]) { - return memcmp(addr1, addr2, ETH_ALEN * sizeof(uint8_t)) == 0; -} - -int mac_is_greater(uint8_t addr1[], uint8_t addr2[]) { - for (int i = 0; i < ETH_ALEN; i++) { - if (addr1[i] > addr2[i]) { - return 1; - } - if (addr1[i] < addr2[i]) { - return 0; - } - - // if equal continue... - } - return 0; -} void print_probe_entry(probe_entry entry) { +#ifndef DAWN_NO_OUTPUT char mac_buf_ap[20]; char mac_buf_client[20]; char mac_buf_target[20]; @@ -1081,14 +1196,17 @@ void print_probe_entry(probe_entry entry) { sprintf(mac_buf_client, MACSTR, MAC2STR(entry.client_addr)); sprintf(mac_buf_target, MACSTR, MAC2STR(entry.target_addr)); + printf( "bssid_addr: %s, client_addr: %s, signal: %d, freq: " "%d, counter: %d, vht: %d, min_rate: %d, max_rate: %d\n", mac_buf_ap, mac_buf_client, entry.signal, entry.freq, entry.counter, entry.vht_capabilities, entry.min_supp_datarate, entry.max_supp_datarate); +#endif } void print_auth_entry(auth_entry entry) { +#ifndef DAWN_NO_OUTPUT char mac_buf_ap[20]; char mac_buf_client[20]; char mac_buf_target[20]; @@ -1101,9 +1219,11 @@ void print_auth_entry(auth_entry entry) { "bssid_addr: %s, client_addr: %s, signal: %d, freq: " "%d\n", mac_buf_ap, mac_buf_client, entry.signal, entry.freq); +#endif } void print_client_entry(client entry) { +#ifndef DAWN_NO_OUTPUT char mac_buf_ap[20]; char mac_buf_client[20]; @@ -1113,6 +1233,7 @@ void print_client_entry(client entry) { printf("bssid_addr: %s, client_addr: %s, freq: %d, ht_supported: %d, vht_supported: %d, ht: %d, vht: %d, kick: %d\n", mac_buf_ap, mac_buf_client, entry.freq, entry.ht_supported, entry.vht_supported, entry.ht, entry.vht, entry.kick_count); +#endif } void print_client_array() { @@ -1124,7 +1245,8 @@ void print_client_array() { printf("------------------\n"); } -void print_ap_entry(ap entry) { +static void print_ap_entry(ap entry) { +#ifndef DAWN_NO_OUTPUT char mac_buf_ap[20]; sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr)); @@ -1133,6 +1255,7 @@ void print_ap_entry(ap entry) { entry.channel_utilization, entry.collision_domain, entry.bandwidth, ap_get_collision_count(entry.collision_domain), entry.neighbor_report ); +#endif } void print_ap_array() { @@ -1142,3 +1265,38 @@ void print_ap_array() { } printf("------------------\n"); } + +void destroy_mutex() { + + // free resources + fprintf(stdout, "Freeing mutex resources\n"); + pthread_mutex_destroy(&probe_array_mutex); + pthread_mutex_destroy(&client_array_mutex); + pthread_mutex_destroy(&ap_array_mutex); + + return; +} + +int init_mutex() { + + if (pthread_mutex_init(&probe_array_mutex, NULL) != 0) { + fprintf(stderr, "Mutex init failed!\n"); + return 1; + } + + if (pthread_mutex_init(&client_array_mutex, NULL) != 0) { + fprintf(stderr, "Mutex init failed!\n"); + return 1; + } + + if (pthread_mutex_init(&ap_array_mutex, NULL) != 0) { + fprintf(stderr, "Mutex init failed!\n"); + return 1; + } + + if (pthread_mutex_init(&denied_array_mutex, NULL) != 0) { + fprintf(stderr, "Mutex init failed!\n"); + return 1; + } + return 0; +} diff --git a/src/storage/uface.c b/src/storage/uface.c deleted file mode 100644 index ffa7d30..0000000 --- a/src/storage/uface.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include "datastorage.h" -#include "utils.h" -#include "ubus.h" -#include "uface.h" - -void remove_probe_array_cb(struct uloop_timeout *t); - -struct uloop_timeout probe_timeout = { - .cb = remove_probe_array_cb -}; - -void remove_client_array_cb(struct uloop_timeout *t); - -struct uloop_timeout client_timeout = { - .cb = remove_client_array_cb -}; - -void remove_ap_array_cb(struct uloop_timeout *t); - -struct uloop_timeout ap_timeout = { - .cb = remove_ap_array_cb -}; - -void denied_req_array_cb(struct uloop_timeout *t); - -struct uloop_timeout denied_req_timeout = { - .cb = denied_req_array_cb -}; - -void uloop_add_data_cbs() { - uloop_timeout_add(&probe_timeout); - uloop_timeout_add(&client_timeout); - uloop_timeout_add(&ap_timeout); - - if (dawn_metric.use_driver_recog) { - uloop_timeout_add(&denied_req_timeout); - } -} - -void remove_probe_array_cb(struct uloop_timeout *t) { - pthread_mutex_lock(&probe_array_mutex); - printf("[Thread] : Removing old probe entries!\n"); - remove_old_probe_entries(time(0), timeout_config.remove_probe); - printf("[Thread] : Removing old entries finished!\n"); - pthread_mutex_unlock(&probe_array_mutex); - uloop_timeout_set(&probe_timeout, timeout_config.remove_probe * 1000); -} - -void remove_client_array_cb(struct uloop_timeout *t) { - pthread_mutex_lock(&client_array_mutex); - printf("[Thread] : Removing old client entries!\n"); - remove_old_client_entries(time(0), timeout_config.update_client); - pthread_mutex_unlock(&client_array_mutex); - uloop_timeout_set(&client_timeout, timeout_config.update_client * 1000); -} - -void remove_ap_array_cb(struct uloop_timeout *t) { - pthread_mutex_lock(&ap_array_mutex); - printf("[ULOOP] : Removing old ap entries!\n"); - remove_old_ap_entries(time(0), timeout_config.remove_ap); - pthread_mutex_unlock(&ap_array_mutex); - uloop_timeout_set(&ap_timeout, timeout_config.remove_ap * 1000); -} - -void denied_req_array_cb(struct uloop_timeout *t) { - pthread_mutex_lock(&denied_array_mutex); - printf("[ULOOP] : Processing denied authentication!\n"); - - time_t current_time = time(0); - - for (int i = 0; i <= denied_req_last; i++) { - // check counter - - //check timer - if (denied_req_array[i].time < current_time - timeout_config.denied_req_threshold) { - - // client is not connected for a given time threshold! - if (!is_connected_somehwere(denied_req_array[i].client_addr)) { - printf("Client has probably a bad driver!\n"); - - // problem that somehow station will land into this list - // maybe delete again? - if (insert_to_maclist(denied_req_array[i].client_addr) == 0) { - send_add_mac(denied_req_array[i].client_addr); -// TODO: File can grow arbitarily large. Resource consumption risk. -// TODO: Consolidate use of file across source: shared resource for name, single point of access? - write_mac_to_file("/tmp/dawn_mac_list", denied_req_array[i].client_addr); - } - } - denied_req_array_delete(denied_req_array[i]); - } - } - pthread_mutex_unlock(&denied_array_mutex); - uloop_timeout_set(&denied_req_timeout, timeout_config.denied_req_threshold * 1000); -} diff --git a/src/test/faketime.script b/src/test/faketime.script new file mode 100644 index 0000000..9c7049d --- /dev/null +++ b/src/test/faketime.script @@ -0,0 +1,25 @@ +faketime set 2000 +faketime show +faketime add 100 +faketime show +faketime auto +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show +faketime show diff --git a/src/test/load_ap.script b/src/test/load_ap.script new file mode 100644 index 0000000..ad73522 --- /dev/null +++ b/src/test/load_ap.script @@ -0,0 +1,3 @@ +ap_show +ap bssid=00:11:22:33:44:55 freq=1 ht_sup=2 vht_sup=3 util=4 time=5 stations=6 ssid=helloWorld col_d=7 bandwidth=8 neighbors= +ap_show diff --git a/src/test/load_auth.script b/src/test/load_auth.script new file mode 100644 index 0000000..fec347d --- /dev/null +++ b/src/test/load_auth.script @@ -0,0 +1,3 @@ +auth_entry_show +auth_entry bssid=00:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa target=99:99:99:99:99:99 signal=1 freq=2 counter=3 +auth_entry_show diff --git a/src/test/load_client.script b/src/test/load_client.script new file mode 100644 index 0000000..d3538ee --- /dev/null +++ b/src/test/load_client.script @@ -0,0 +1,3 @@ +client_show +client bssid=00:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa freq=1 ht_sup=2 vht_sup=3 ht=4 vht=5 kick=6 +client_show diff --git a/src/test/load_probe.script b/src/test/load_probe.script new file mode 100644 index 0000000..f8c4752 --- /dev/null +++ b/src/test/load_probe.script @@ -0,0 +1,5 @@ +elapsed +probe_show +probe bssid=00:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa signal=1 freq=2 counter=3 vht_cap=4 min_rate=5 max_rate=6 +probe_show +elapsed diff --git a/src/test/mac_simple.script b/src/test/mac_simple.script new file mode 100644 index 0000000..94dcf42 --- /dev/null +++ b/src/test/mac_simple.script @@ -0,0 +1,4 @@ +macadd aa:bb:cc:dd:ee:ff +macadd 11:22:33:44:55:66 +macget aa:bb:cc:dd:ee:ff +macget 99:aa:bb:cc:dd:ee diff --git a/src/test/old_ap.script b/src/test/old_ap.script new file mode 100644 index 0000000..9a6fd51 --- /dev/null +++ b/src/test/old_ap.script @@ -0,0 +1,31 @@ +faketime set 100 +ap_show +remove_old_ap_entries 50 + +faketime show +ap bssid=00:11:22:33:44:55 freq=1 ht_sup=2 vht_sup=3 util=4 stations=6 ssid=helloWorld col_d=7 bandwidth=8 neighbors= + +faketime add 25 +faketime show +ap bssid=01:11:22:33:44:55 freq=1 ht_sup=2 vht_sup=3 util=4 stations=6 ssid=helloWorld col_d=7 bandwidth=8 neighbors= + +faketime add 25 +faketime show +ap bssid=02:11:22:33:44:55 freq=1 ht_sup=2 vht_sup=3 util=4 stations=6 ssid=helloWorld col_d=7 bandwidth=8 neighbors= + +faketime add 25 +faketime show +ap bssid=03:11:22:33:44:55 freq=1 ht_sup=2 vht_sup=3 util=4 stations=6 ssid=helloWorld col_d=7 bandwidth=8 neighbors= + +faketime add 25 +faketime show +ap bssid=04:11:22:33:44:55 freq=1 ht_sup=2 vht_sup=3 util=4 stations=6 ssid=helloWorld col_d=7 bandwidth=8 neighbors= + +ap_show + +remove_old_ap_entries 50 +ap_show + +faketime add 25 +remove_old_ap_entries 0 +ap_show diff --git a/src/test/old_auth.script b/src/test/old_auth.script new file mode 100644 index 0000000..4feb573 --- /dev/null +++ b/src/test/old_auth.script @@ -0,0 +1,30 @@ +faketime set 100 +auth_entry_show +remove_old_auth_entries 50 + +faketime show +auth_entry bssid=00:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +auth_entry bssid=01:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +auth_entry bssid=02:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +auth_entry bssid=03:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +auth_entry bssid=04:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +auth_entry_show + +remove_old_auth_entries 50 +auth_entry_show + +remove_old_auth_entries 0 +auth_entry_show diff --git a/src/test/old_client.script b/src/test/old_client.script new file mode 100644 index 0000000..e83bca2 --- /dev/null +++ b/src/test/old_client.script @@ -0,0 +1,31 @@ +faketime set 100 +client_show +remove_old_client_entries 50 + +faketime show +client bssid=00:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +client bssid=01:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +client bssid=02:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +client bssid=03:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +client bssid=04:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +client_show + +remove_old_client_entries 50 +client_show + +faketime add 25 +remove_old_client_entries 0 +client_show diff --git a/src/test/old_probe.script b/src/test/old_probe.script new file mode 100644 index 0000000..1fe26f9 --- /dev/null +++ b/src/test/old_probe.script @@ -0,0 +1,44 @@ +faketime set 100 +probe_show +remove_old_probe_entries 50 + +faketime show +probe bssid=00:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +probe bssid=01:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +probe bssid=02:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +probe bssid=03:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +faketime add 25 +faketime show +probe bssid=04:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa + +probe_show + +remove_old_probe_entries 50 +probe_show + +faketime add 25 +remove_old_probe_entries 0 +probe_show + +# Test that a still connected client is not removed +faketime set 500 + +faketime show +client bssid=00:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa +probe bssid=00:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa +probe bssid=01:11:22:33:44:55 client=ff:ee:dd:cc:bb:aa +probe_show + +faketime add 25 +remove_old_probe_entries 0 +probe_show diff --git a/src/test/probe_auto.script b/src/test/probe_auto.script index cc3cf03..42ea2a0 100644 --- a/src/test/probe_auto.script +++ b/src/test/probe_auto.script @@ -1,5 +1,4 @@ # Basic test of array entry handling -probe_sort bcfs probe_add_auto 10 20 probe_show probe_del_auto 10 20 diff --git a/src/test/scale_test_A.script b/src/test/scale_test_A.script new file mode 100644 index 0000000..4e89139 --- /dev/null +++ b/src/test/scale_test_A.script @@ -0,0 +1,420 @@ +elapsed + +# DAWN mertics to help testing output review +dawn default +dawn ht_support=8 +dawn vht_support=16 +dawn max_chan_util=0 +dawn ap_weight=4 +dawn rssi=32 +dawn low_rssi=0 +dawn min_kick_count=1 + + +#AP +ap bssid=0A:7B:AA:00:01:00 ht_sup=1 vht_sup=1 util=156 stations=13 ssid=aTestSSID weight=10 neighbors=0A:7B:AA:00:01:00 +ap bssid=02:67:AA:00:02:00 ht_sup=1 vht_sup=1 util=195 stations=13 ssid=aTestSSID weight=10 neighbors=02:67:AA:00:02:00 +ap bssid=14:02:AA:00:03:00 ht_sup=1 vht_sup=1 util=126 stations=9 ssid=aTestSSID weight=10 neighbors=14:02:AA:00:03:00 +ap bssid=1F:36:AA:00:04:00 ht_sup=0 vht_sup=0 util=120 stations=8 ssid=aTestSSID weight=10 neighbors=1F:36:AA:00:04:00 +ap bssid=69:E9:AA:00:05:00 ht_sup=0 vht_sup=0 util=44 stations=4 ssid=aTestSSID weight=10 neighbors=69:E9:AA:00:05:00 +ap bssid=6A:97:AA:00:06:00 ht_sup=0 vht_sup=0 util=110 stations=11 ssid=aTestSSID weight=10 neighbors=6A:97:AA:00:06:00 +ap bssid=45:63:AA:00:07:00 ht_sup=0 vht_sup=0 util=55 stations=5 ssid=aTestSSID weight=10 neighbors=45:63:AA:00:07:00 +ap bssid=07:1E:AA:00:08:00 ht_sup=1 vht_sup=1 util=88 stations=8 ssid=aTestSSID weight=10 neighbors=07:1E:AA:00:08:00 +ap bssid=45:A2:AA:00:09:00 ht_sup=0 vht_sup=0 util=120 stations=12 ssid=aTestSSID weight=10 neighbors=45:A2:AA:00:09:00 +ap bssid=4C:4D:AA:00:0A:00 ht_sup=1 vht_sup=1 util=195 stations=13 ssid=aTestSSID weight=10 neighbors=4C:4D:AA:00:0A:00 + +#Client +client client=50:7B:DD:00:01:00 bssid=45:A2:AA:00:09:00 freq=2500 ht_cap=1 vht_cap=1 +client client=22:87:DD:00:02:00 bssid=4C:4D:AA:00:0A:00 freq=5500 ht_cap=0 vht_cap=0 +client client=54:1A:DD:00:03:00 bssid=14:02:AA:00:03:00 freq=5500 ht_cap=1 vht_cap=0 +client client=60:79:DD:00:04:00 bssid=0A:7B:AA:00:01:00 freq=5500 ht_cap=1 vht_cap=0 +client client=20:EE:DD:00:05:00 bssid=07:1E:AA:00:08:00 freq=2500 ht_cap=0 vht_cap=0 +client client=33:D2:DD:00:06:00 bssid=45:63:AA:00:07:00 freq=5500 ht_cap=1 vht_cap=1 +client client=44:B6:DD:00:07:00 bssid=69:E9:AA:00:05:00 freq=2500 ht_cap=1 vht_cap=1 +client client=3A:D6:DD:00:08:00 bssid=1F:36:AA:00:04:00 freq=2500 ht_cap=0 vht_cap=0 +client client=3C:BB:DD:00:09:00 bssid=69:E9:AA:00:05:00 freq=5500 ht_cap=1 vht_cap=0 +client client=2D:3F:DD:00:0A:00 bssid=14:02:AA:00:03:00 freq=5500 ht_cap=1 vht_cap=1 +client client=00:08:DD:00:0B:00 bssid=45:A2:AA:00:09:00 freq=5500 ht_cap=0 vht_cap=0 +client client=64:5A:DD:00:0C:00 bssid=45:A2:AA:00:09:00 freq=2500 ht_cap=0 vht_cap=0 +client client=13:ED:DD:00:0D:00 bssid=14:02:AA:00:03:00 freq=2500 ht_cap=1 vht_cap=0 +client client=3B:43:DD:00:0E:00 bssid=1F:36:AA:00:04:00 freq=2500 ht_cap=0 vht_cap=0 +client client=10:6A:DD:00:0F:00 bssid=14:02:AA:00:03:00 freq=2500 ht_cap=0 vht_cap=0 +client client=0D:BE:DD:00:10:00 bssid=6A:97:AA:00:06:00 freq=5500 ht_cap=1 vht_cap=0 +client client=3E:B5:DD:00:11:00 bssid=07:1E:AA:00:08:00 freq=2500 ht_cap=0 vht_cap=0 +client client=41:C2:DD:00:12:00 bssid=0A:7B:AA:00:01:00 freq=5500 ht_cap=0 vht_cap=0 +client client=2A:75:DD:00:13:00 bssid=6A:97:AA:00:06:00 freq=5500 ht_cap=0 vht_cap=0 +client client=31:FB:DD:00:14:00 bssid=02:67:AA:00:02:00 freq=2500 ht_cap=1 vht_cap=0 +client client=2E:B8:DD:00:15:00 bssid=14:02:AA:00:03:00 freq=5500 ht_cap=0 vht_cap=0 +client client=40:50:DD:00:16:00 bssid=69:E9:AA:00:05:00 freq=5500 ht_cap=0 vht_cap=0 +client client=0D:7F:DD:00:17:00 bssid=1F:36:AA:00:04:00 freq=5500 ht_cap=1 vht_cap=0 +client client=40:C7:DD:00:18:00 bssid=1F:36:AA:00:04:00 freq=5500 ht_cap=1 vht_cap=1 +client client=31:F5:DD:00:19:00 bssid=14:02:AA:00:03:00 freq=5500 ht_cap=1 vht_cap=0 +client client=56:C7:DD:00:1A:00 bssid=07:1E:AA:00:08:00 freq=2500 ht_cap=0 vht_cap=0 +client client=09:77:DD:00:1B:00 bssid=69:E9:AA:00:05:00 freq=5500 ht_cap=0 vht_cap=0 +client client=53:C7:DD:00:1C:00 bssid=14:02:AA:00:03:00 freq=5500 ht_cap=0 vht_cap=0 +client client=07:CC:DD:00:1D:00 bssid=02:67:AA:00:02:00 freq=2500 ht_cap=1 vht_cap=1 +client client=37:13:DD:00:1E:00 bssid=45:63:AA:00:07:00 freq=2500 ht_cap=1 vht_cap=0 +client client=1A:ED:DD:00:1F:00 bssid=4C:4D:AA:00:0A:00 freq=2500 ht_cap=0 vht_cap=0 +client client=78:22:DD:00:20:00 bssid=0A:7B:AA:00:01:00 freq=5500 ht_cap=0 vht_cap=0 +client client=7D:52:DD:00:21:00 bssid=45:A2:AA:00:09:00 freq=2500 ht_cap=0 vht_cap=0 +client client=75:45:DD:00:22:00 bssid=07:1E:AA:00:08:00 freq=2500 ht_cap=0 vht_cap=0 + +#Probe +probe bssid=0A:7B:AA:00:01:00 client=50:7B:DD:00:01:00 signal=-65 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=0A:7B:AA:00:01:00 client=22:87:DD:00:02:00 signal=-71 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=54:1A:DD:00:03:00 signal=-76 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=60:79:DD:00:04:00 signal=-84 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=20:EE:DD:00:05:00 signal=-65 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=33:D2:DD:00:06:00 signal=-77 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=0A:7B:AA:00:01:00 client=44:B6:DD:00:07:00 signal=-79 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=0A:7B:AA:00:01:00 client=3A:D6:DD:00:08:00 signal=-82 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=3C:BB:DD:00:09:00 signal=-91 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=2D:3F:DD:00:0A:00 signal=-82 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=0A:7B:AA:00:01:00 client=00:08:DD:00:0B:00 signal=-85 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=64:5A:DD:00:0C:00 signal=-80 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=13:ED:DD:00:0D:00 signal=-78 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=3B:43:DD:00:0E:00 signal=-69 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=10:6A:DD:00:0F:00 signal=-83 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=0D:BE:DD:00:10:00 signal=-81 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=3E:B5:DD:00:11:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=41:C2:DD:00:12:00 signal=-78 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=2A:75:DD:00:13:00 signal=-91 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=31:FB:DD:00:14:00 signal=-69 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=2E:B8:DD:00:15:00 signal=-78 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=40:50:DD:00:16:00 signal=-81 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=0D:7F:DD:00:17:00 signal=-86 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=40:C7:DD:00:18:00 signal=-91 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=0A:7B:AA:00:01:00 client=31:F5:DD:00:19:00 signal=-84 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=56:C7:DD:00:1A:00 signal=-84 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=09:77:DD:00:1B:00 signal=-87 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=53:C7:DD:00:1C:00 signal=-75 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=07:CC:DD:00:1D:00 signal=-88 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=0A:7B:AA:00:01:00 client=37:13:DD:00:1E:00 signal=-79 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=1A:ED:DD:00:1F:00 signal=-81 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=78:22:DD:00:20:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=7D:52:DD:00:21:00 signal=-89 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=0A:7B:AA:00:01:00 client=75:45:DD:00:22:00 signal=-79 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=50:7B:DD:00:01:00 signal=-82 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=02:67:AA:00:02:00 client=22:87:DD:00:02:00 signal=-81 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=54:1A:DD:00:03:00 signal=-86 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=60:79:DD:00:04:00 signal=-72 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=20:EE:DD:00:05:00 signal=-84 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=33:D2:DD:00:06:00 signal=-84 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=02:67:AA:00:02:00 client=44:B6:DD:00:07:00 signal=-73 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=02:67:AA:00:02:00 client=3A:D6:DD:00:08:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=3C:BB:DD:00:09:00 signal=-88 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=2D:3F:DD:00:0A:00 signal=-83 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=02:67:AA:00:02:00 client=00:08:DD:00:0B:00 signal=-76 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=64:5A:DD:00:0C:00 signal=-87 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=13:ED:DD:00:0D:00 signal=-84 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=3B:43:DD:00:0E:00 signal=-84 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=10:6A:DD:00:0F:00 signal=-91 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=0D:BE:DD:00:10:00 signal=-76 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=3E:B5:DD:00:11:00 signal=-74 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=41:C2:DD:00:12:00 signal=-84 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=2A:75:DD:00:13:00 signal=-88 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=31:FB:DD:00:14:00 signal=-80 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=2E:B8:DD:00:15:00 signal=-84 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=40:50:DD:00:16:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=0D:7F:DD:00:17:00 signal=-71 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=40:C7:DD:00:18:00 signal=-86 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=02:67:AA:00:02:00 client=31:F5:DD:00:19:00 signal=-62 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=56:C7:DD:00:1A:00 signal=-78 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=09:77:DD:00:1B:00 signal=-79 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=53:C7:DD:00:1C:00 signal=-83 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=07:CC:DD:00:1D:00 signal=-89 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=02:67:AA:00:02:00 client=37:13:DD:00:1E:00 signal=-78 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=1A:ED:DD:00:1F:00 signal=-74 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=78:22:DD:00:20:00 signal=-87 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=7D:52:DD:00:21:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=02:67:AA:00:02:00 client=75:45:DD:00:22:00 signal=-71 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=50:7B:DD:00:01:00 signal=-65 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=14:02:AA:00:03:00 client=22:87:DD:00:02:00 signal=-83 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=54:1A:DD:00:03:00 signal=-84 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=60:79:DD:00:04:00 signal=-90 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=20:EE:DD:00:05:00 signal=-62 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=33:D2:DD:00:06:00 signal=-86 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=14:02:AA:00:03:00 client=44:B6:DD:00:07:00 signal=-87 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=14:02:AA:00:03:00 client=3A:D6:DD:00:08:00 signal=-89 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=3C:BB:DD:00:09:00 signal=-95 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=2D:3F:DD:00:0A:00 signal=-89 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=14:02:AA:00:03:00 client=00:08:DD:00:0B:00 signal=-86 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=64:5A:DD:00:0C:00 signal=-87 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=13:ED:DD:00:0D:00 signal=-71 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=3B:43:DD:00:0E:00 signal=-60 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=10:6A:DD:00:0F:00 signal=-87 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=0D:BE:DD:00:10:00 signal=-89 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=3E:B5:DD:00:11:00 signal=-91 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=41:C2:DD:00:12:00 signal=-69 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=2A:75:DD:00:13:00 signal=-95 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=31:FB:DD:00:14:00 signal=-70 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=2E:B8:DD:00:15:00 signal=-86 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=40:50:DD:00:16:00 signal=-67 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=0D:7F:DD:00:17:00 signal=-89 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=40:C7:DD:00:18:00 signal=-95 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=14:02:AA:00:03:00 client=31:F5:DD:00:19:00 signal=-88 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=56:C7:DD:00:1A:00 signal=-84 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=09:77:DD:00:1B:00 signal=-92 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=53:C7:DD:00:1C:00 signal=-68 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=07:CC:DD:00:1D:00 signal=-92 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=14:02:AA:00:03:00 client=37:13:DD:00:1E:00 signal=-78 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=1A:ED:DD:00:1F:00 signal=-88 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=78:22:DD:00:20:00 signal=-94 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=7D:52:DD:00:21:00 signal=-94 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=14:02:AA:00:03:00 client=75:45:DD:00:22:00 signal=-87 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=50:7B:DD:00:01:00 signal=-80 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=1F:36:AA:00:04:00 client=22:87:DD:00:02:00 signal=-87 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=54:1A:DD:00:03:00 signal=-90 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=60:79:DD:00:04:00 signal=-86 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=20:EE:DD:00:05:00 signal=-83 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=33:D2:DD:00:06:00 signal=-89 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=1F:36:AA:00:04:00 client=44:B6:DD:00:07:00 signal=-86 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=1F:36:AA:00:04:00 client=3A:D6:DD:00:08:00 signal=-91 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=3C:BB:DD:00:09:00 signal=-95 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=2D:3F:DD:00:0A:00 signal=-91 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=1F:36:AA:00:04:00 client=00:08:DD:00:0B:00 signal=-67 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=64:5A:DD:00:0C:00 signal=-91 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=13:ED:DD:00:0D:00 signal=-75 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=3B:43:DD:00:0E:00 signal=-81 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=10:6A:DD:00:0F:00 signal=-94 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=0D:BE:DD:00:10:00 signal=-88 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=3E:B5:DD:00:11:00 signal=-87 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=41:C2:DD:00:12:00 signal=-76 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=2A:75:DD:00:13:00 signal=-94 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=31:FB:DD:00:14:00 signal=-77 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=2E:B8:DD:00:15:00 signal=-90 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=40:50:DD:00:16:00 signal=-84 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=0D:7F:DD:00:17:00 signal=-77 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=40:C7:DD:00:18:00 signal=-93 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=1F:36:AA:00:04:00 client=31:F5:DD:00:19:00 signal=-77 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=56:C7:DD:00:1A:00 signal=-50 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=09:77:DD:00:1B:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=53:C7:DD:00:1C:00 signal=-76 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=07:CC:DD:00:1D:00 signal=-94 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=1F:36:AA:00:04:00 client=37:13:DD:00:1E:00 signal=-64 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=1A:ED:DD:00:1F:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=78:22:DD:00:20:00 signal=-93 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=7D:52:DD:00:21:00 signal=-93 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=1F:36:AA:00:04:00 client=75:45:DD:00:22:00 signal=-85 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=50:7B:DD:00:01:00 signal=-69 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=69:E9:AA:00:05:00 client=22:87:DD:00:02:00 signal=-74 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=54:1A:DD:00:03:00 signal=-75 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=60:79:DD:00:04:00 signal=-87 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=20:EE:DD:00:05:00 signal=-64 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=33:D2:DD:00:06:00 signal=-78 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=69:E9:AA:00:05:00 client=44:B6:DD:00:07:00 signal=-83 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=69:E9:AA:00:05:00 client=3A:D6:DD:00:08:00 signal=-83 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=3C:BB:DD:00:09:00 signal=-92 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=2D:3F:DD:00:0A:00 signal=-84 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=69:E9:AA:00:05:00 client=00:08:DD:00:0B:00 signal=-88 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=64:5A:DD:00:0C:00 signal=-80 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=13:ED:DD:00:0D:00 signal=-79 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=3B:43:DD:00:0E:00 signal=-69 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=10:6A:DD:00:0F:00 signal=-81 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=0D:BE:DD:00:10:00 signal=-84 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=3E:B5:DD:00:11:00 signal=-89 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=41:C2:DD:00:12:00 signal=-79 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=2A:75:DD:00:13:00 signal=-92 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=31:FB:DD:00:14:00 signal=-74 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=2E:B8:DD:00:15:00 signal=-79 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=40:50:DD:00:16:00 signal=-80 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=0D:7F:DD:00:17:00 signal=-89 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=40:C7:DD:00:18:00 signal=-92 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=69:E9:AA:00:05:00 client=31:F5:DD:00:19:00 signal=-87 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=56:C7:DD:00:1A:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=09:77:DD:00:1B:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=53:C7:DD:00:1C:00 signal=-77 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=07:CC:DD:00:1D:00 signal=-88 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=69:E9:AA:00:05:00 client=37:13:DD:00:1E:00 signal=-82 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=1A:ED:DD:00:1F:00 signal=-85 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=78:22:DD:00:20:00 signal=-90 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=7D:52:DD:00:21:00 signal=-90 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=69:E9:AA:00:05:00 client=75:45:DD:00:22:00 signal=-83 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=50:7B:DD:00:01:00 signal=-70 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=6A:97:AA:00:06:00 client=22:87:DD:00:02:00 signal=-79 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=54:1A:DD:00:03:00 signal=-79 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=60:79:DD:00:04:00 signal=-89 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=20:EE:DD:00:05:00 signal=-64 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=33:D2:DD:00:06:00 signal=-82 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=6A:97:AA:00:06:00 client=44:B6:DD:00:07:00 signal=-86 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=6A:97:AA:00:06:00 client=3A:D6:DD:00:08:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=3C:BB:DD:00:09:00 signal=-94 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=2D:3F:DD:00:0A:00 signal=-87 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=6A:97:AA:00:06:00 client=00:08:DD:00:0B:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=64:5A:DD:00:0C:00 signal=-83 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=13:ED:DD:00:0D:00 signal=-79 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=3B:43:DD:00:0E:00 signal=-69 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=10:6A:DD:00:0F:00 signal=-82 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=0D:BE:DD:00:10:00 signal=-87 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=3E:B5:DD:00:11:00 signal=-90 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=41:C2:DD:00:12:00 signal=-79 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=2A:75:DD:00:13:00 signal=-94 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=31:FB:DD:00:14:00 signal=-75 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=2E:B8:DD:00:15:00 signal=-82 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=40:50:DD:00:16:00 signal=-78 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=0D:7F:DD:00:17:00 signal=-90 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=40:C7:DD:00:18:00 signal=-94 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=6A:97:AA:00:06:00 client=31:F5:DD:00:19:00 signal=-89 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=56:C7:DD:00:1A:00 signal=-87 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=09:77:DD:00:1B:00 signal=-91 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=53:C7:DD:00:1C:00 signal=-77 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=07:CC:DD:00:1D:00 signal=-90 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=6A:97:AA:00:06:00 client=37:13:DD:00:1E:00 signal=-83 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=1A:ED:DD:00:1F:00 signal=-87 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=78:22:DD:00:20:00 signal=-92 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=7D:52:DD:00:21:00 signal=-92 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=6A:97:AA:00:06:00 client=75:45:DD:00:22:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=50:7B:DD:00:01:00 signal=-69 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=45:63:AA:00:07:00 client=22:87:DD:00:02:00 signal=-83 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=54:1A:DD:00:03:00 signal=-86 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=60:79:DD:00:04:00 signal=-86 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=20:EE:DD:00:05:00 signal=-74 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=33:D2:DD:00:06:00 signal=-86 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=45:63:AA:00:07:00 client=44:B6:DD:00:07:00 signal=-84 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=45:63:AA:00:07:00 client=3A:D6:DD:00:08:00 signal=-89 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=3C:BB:DD:00:09:00 signal=-94 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=2D:3F:DD:00:0A:00 signal=-88 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=45:63:AA:00:07:00 client=00:08:DD:00:0B:00 signal=-78 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=64:5A:DD:00:0C:00 signal=-88 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=13:ED:DD:00:0D:00 signal=-60 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=3B:43:DD:00:0E:00 signal=-70 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=10:6A:DD:00:0F:00 signal=-90 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=0D:BE:DD:00:10:00 signal=-86 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=3E:B5:DD:00:11:00 signal=-88 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=41:C2:DD:00:12:00 signal=-64 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=2A:75:DD:00:13:00 signal=-94 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=31:FB:DD:00:14:00 signal=-62 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=2E:B8:DD:00:15:00 signal=-87 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=40:50:DD:00:16:00 signal=-77 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=0D:7F:DD:00:17:00 signal=-82 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=40:C7:DD:00:18:00 signal=-93 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=45:63:AA:00:07:00 client=31:F5:DD:00:19:00 signal=-81 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=56:C7:DD:00:1A:00 signal=-74 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=09:77:DD:00:1B:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=53:C7:DD:00:1C:00 signal=-58 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=07:CC:DD:00:1D:00 signal=-93 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=45:63:AA:00:07:00 client=37:13:DD:00:1E:00 signal=-60 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=1A:ED:DD:00:1F:00 signal=-85 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=78:22:DD:00:20:00 signal=-92 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=7D:52:DD:00:21:00 signal=-92 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:63:AA:00:07:00 client=75:45:DD:00:22:00 signal=-83 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=50:7B:DD:00:01:00 signal=-76 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=07:1E:AA:00:08:00 client=22:87:DD:00:02:00 signal=-83 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=54:1A:DD:00:03:00 signal=-87 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=60:79:DD:00:04:00 signal=-82 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=20:EE:DD:00:05:00 signal=-79 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=33:D2:DD:00:06:00 signal=-86 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=07:1E:AA:00:08:00 client=44:B6:DD:00:07:00 signal=-80 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=07:1E:AA:00:08:00 client=3A:D6:DD:00:08:00 signal=-88 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=3C:BB:DD:00:09:00 signal=-92 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=2D:3F:DD:00:0A:00 signal=-87 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=07:1E:AA:00:08:00 client=00:08:DD:00:0B:00 signal=-71 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=64:5A:DD:00:0C:00 signal=-88 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=13:ED:DD:00:0D:00 signal=-75 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=3B:43:DD:00:0E:00 signal=-78 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=10:6A:DD:00:0F:00 signal=-91 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=0D:BE:DD:00:10:00 signal=-83 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=3E:B5:DD:00:11:00 signal=-84 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=41:C2:DD:00:12:00 signal=-76 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=2A:75:DD:00:13:00 signal=-92 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=31:FB:DD:00:14:00 signal=-72 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=2E:B8:DD:00:15:00 signal=-86 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=40:50:DD:00:16:00 signal=-83 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=0D:7F:DD:00:17:00 signal=-76 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=40:C7:DD:00:18:00 signal=-91 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=07:1E:AA:00:08:00 client=31:F5:DD:00:19:00 signal=-74 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=56:C7:DD:00:1A:00 signal=-69 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=09:77:DD:00:1B:00 signal=-86 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=53:C7:DD:00:1C:00 signal=-74 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=07:CC:DD:00:1D:00 signal=-92 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=07:1E:AA:00:08:00 client=37:13:DD:00:1E:00 signal=-60 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=1A:ED:DD:00:1F:00 signal=-82 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=78:22:DD:00:20:00 signal=-91 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=7D:52:DD:00:21:00 signal=-91 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=07:1E:AA:00:08:00 client=75:45:DD:00:22:00 signal=-79 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=50:7B:DD:00:01:00 signal=-84 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=45:A2:AA:00:09:00 client=22:87:DD:00:02:00 signal=-86 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=54:1A:DD:00:03:00 signal=-90 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=60:79:DD:00:04:00 signal=-80 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=20:EE:DD:00:05:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=33:D2:DD:00:06:00 signal=-88 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=45:A2:AA:00:09:00 client=44:B6:DD:00:07:00 signal=-81 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=45:A2:AA:00:09:00 client=3A:D6:DD:00:08:00 signal=-90 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=3C:BB:DD:00:09:00 signal=-92 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=2D:3F:DD:00:0A:00 signal=-88 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=45:A2:AA:00:09:00 client=00:08:DD:00:0B:00 signal=-62 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=64:5A:DD:00:0C:00 signal=-90 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=13:ED:DD:00:0D:00 signal=-83 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=3B:43:DD:00:0E:00 signal=-85 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=10:6A:DD:00:0F:00 signal=-94 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=0D:BE:DD:00:10:00 signal=-84 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=3E:B5:DD:00:11:00 signal=-81 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=41:C2:DD:00:12:00 signal=-84 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=2A:75:DD:00:13:00 signal=-91 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=31:FB:DD:00:14:00 signal=-82 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=2E:B8:DD:00:15:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=40:50:DD:00:16:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=0D:7F:DD:00:17:00 signal=-56 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=40:C7:DD:00:18:00 signal=-89 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=45:A2:AA:00:09:00 client=31:F5:DD:00:19:00 signal=-58 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=56:C7:DD:00:1A:00 signal=-72 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=09:77:DD:00:1B:00 signal=-84 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=53:C7:DD:00:1C:00 signal=-83 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=07:CC:DD:00:1D:00 signal=-93 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=45:A2:AA:00:09:00 client=37:13:DD:00:1E:00 signal=-76 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=1A:ED:DD:00:1F:00 signal=-81 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=78:22:DD:00:20:00 signal=-91 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=7D:52:DD:00:21:00 signal=-90 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=45:A2:AA:00:09:00 client=75:45:DD:00:22:00 signal=-80 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=50:7B:DD:00:01:00 signal=-81 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=4C:4D:AA:00:0A:00 client=22:87:DD:00:02:00 signal=-87 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=54:1A:DD:00:03:00 signal=-90 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=60:79:DD:00:04:00 signal=-86 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=20:EE:DD:00:05:00 signal=-84 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=33:D2:DD:00:06:00 signal=-90 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=4C:4D:AA:00:0A:00 client=44:B6:DD:00:07:00 signal=-85 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=4C:4D:AA:00:0A:00 client=3A:D6:DD:00:08:00 signal=-91 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=3C:BB:DD:00:09:00 signal=-94 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=2D:3F:DD:00:0A:00 signal=-90 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=4C:4D:AA:00:0A:00 client=00:08:DD:00:0B:00 signal=-60 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=64:5A:DD:00:0C:00 signal=-91 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=13:ED:DD:00:0D:00 signal=-78 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=3B:43:DD:00:0E:00 signal=-82 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=10:6A:DD:00:0F:00 signal=-94 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=0D:BE:DD:00:10:00 signal=-87 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=3E:B5:DD:00:11:00 signal=-87 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=41:C2:DD:00:12:00 signal=-79 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=2A:75:DD:00:13:00 signal=-94 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=31:FB:DD:00:14:00 signal=-79 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=2E:B8:DD:00:15:00 signal=-90 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=40:50:DD:00:16:00 signal=-85 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=0D:7F:DD:00:17:00 signal=-74 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=40:C7:DD:00:18:00 signal=-93 freq=5500 ht_cap=1 vht_cap=1 +probe bssid=4C:4D:AA:00:0A:00 client=31:F5:DD:00:19:00 signal=-75 freq=5500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=56:C7:DD:00:1A:00 signal=-39 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=09:77:DD:00:1B:00 signal=-89 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=53:C7:DD:00:1C:00 signal=-78 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=07:CC:DD:00:1D:00 signal=-94 freq=2500 ht_cap=1 vht_cap=1 +probe bssid=4C:4D:AA:00:0A:00 client=37:13:DD:00:1E:00 signal=-68 freq=2500 ht_cap=1 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=1A:ED:DD:00:1F:00 signal=-86 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=78:22:DD:00:20:00 signal=-93 freq=5500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=7D:52:DD:00:21:00 signal=-93 freq=2500 ht_cap=0 vht_cap=0 +probe bssid=4C:4D:AA:00:0A:00 client=75:45:DD:00:22:00 signal=-84 freq=2500 ht_cap=0 vht_cap=0 + + +client_show + +kick 0A:7B:AA:00:01:00 0 +kick 02:67:AA:00:02:00 0 +kick 14:02:AA:00:03:00 0 +kick 1F:36:AA:00:04:00 0 +kick 69:E9:AA:00:05:00 0 +kick 6A:97:AA:00:06:00 0 +kick 45:63:AA:00:07:00 0 +kick 07:1E:AA:00:08:00 0 +kick 45:A2:AA:00:09:00 0 +kick 4C:4D:AA:00:0A:00 0 + +client_show + +elapsed diff --git a/src/test/simple_kick.script b/src/test/simple_kick.script new file mode 100644 index 0000000..eeb5989 --- /dev/null +++ b/src/test/simple_kick.script @@ -0,0 +1,5 @@ +dawn min_kick_count=2 +ap bssid=11:22:33:44:55:66 +client bssid=11:22:33:44:55:66 client=ff:ee:dd:cc:bb:aa +kick 11:22:33:44:55:66 0 +kick 11:22:33:44:55:66 0 diff --git a/src/test/test_header.c b/src/test/test_header.c new file mode 100644 index 0000000..9b9aa25 --- /dev/null +++ b/src/test/test_header.c @@ -0,0 +1,9 @@ +// Simple compilation unit to see if a header file can "compile itself" +// Place single header file below to check that it includes anything needed +// to resolve any type references, etc. +#include "datastorage.h" + +int main(int argc, char* argv[]) +{ + return 0; +} \ No newline at end of file diff --git a/src/test/test_storage.c b/src/test/test_storage.c index 24be6e9..b17ff6d 100644 --- a/src/test/test_storage.c +++ b/src/test/test_storage.c @@ -1,27 +1,23 @@ -#include -#include -#include -#include +#include +#include #include "dawn_iwinfo.h" -#include "utils.h" -#include "ieee80211_utils.h" #include "datastorage.h" -#include "uface.h" - -/*** SUT functions we use that are not in header files (like "friend" functions) ***/ -void ap_array_insert(ap entry); -ap ap_array_delete(ap entry); +#include "msghandler.h" +#include "ubus.h" +#include "test_storage.h" /*** Testing structures, etc ***/ +// pac_a_mac allows a 6-byte (48-bit) MAC address to be efficiently handled as a 64-bit integer +#define MAC_MASK_PACKED_U64 0xFFFFFFFFFFFF0000 union __attribute__((__packed__)) pac_a_mac { struct { - uint8_t pos[6]; - uint8_t packing[2]; - } u8; - uint64_t u64; + uint8_t u8[6]; + uint8_t packing[2]; // Not strictly needed as compiler will allocated space for largest member of union + } unpacked; + uint64_t packed_u64; }; /*** Test Stub Functions - Called by SUT ***/ @@ -36,9 +32,26 @@ int send_set_probe(uint8_t client_addr[]) return 0; } -void wnm_disassoc_imminent(uint32_t id, const uint8_t* client_addr, char* dest_ap, uint32_t duration) +int wnm_disassoc_imminent(uint32_t id, const uint8_t* client_addr, char* dest_ap, uint32_t duration) { +int ret = 0; + printf("wnm_disassoc_imminent() was called...\n"); + + if (dest_ap != NULL) + { + // Fake a client being disassociated and then rejoining on the recommended neoghbor + client mc = client_array_get_client(client_addr); + mc = client_array_delete(mc); + hwaddr_aton(dest_ap, mc.bssid_addr); + client_array_insert(mc); + printf("BSS TRANSITION TO %s\n", dest_ap); + + // Tell caller not to change the arrays any further + ret = 1; + } + + return ret; } void add_client_update_timer(time_t time) @@ -71,11 +84,16 @@ int get_expected_throughput_iwinfo(uint8_t* client_addr) int get_bandwidth_iwinfo(uint8_t* client_addr, float* rx_rate, float* tx_rate) { - printf("get_bandwidth_iwinfo() was called...\n"); + *rx_rate = 0.0; + *tx_rate = 0.0; + + printf("get_bandwidth_iwinfo() was called. Returning rx=%1f, tx=%1f...\n", (double)*rx_rate, (double)*tx_rate); return 0; } -/*** Local Function Prototypes ***/ +/*** Local Function Prototypes and Related Constants ***/ +static int array_auto_helper(int action, int i0, int i1); + #define HELPER_ACTION_ADD 0x0000 #define HELPER_ACTION_DEL 0x1000 #define HELPER_ACTION_MASK 0x1000 @@ -85,65 +103,70 @@ int get_bandwidth_iwinfo(uint8_t* client_addr, float* rx_rate, float* tx_rate) #define HELPER_AUTH_ENTRY 0x0004 #define HELPER_PROBE_ARRAY 0x0008 -int array_auto_helper(int action, int i0, int i1); -int client_array_auto_helper(int action, int i0, int i1); -int auth_entry_array_auto_helper(int action, int i0, int i1); -int probe_array_auto_helper(int action, int i0, int i1); +/*** Local globals ***/ +static double base_time; +static double last_time; +static bool first_time = true; -/*** Test narness code */ -int array_auto_helper(int action, int i0, int i1) +static time_t faketime = 1000; +static bool faketime_auto = true; // true = increment every command; false = scripted updates + +/*** Test harness code */ +static int array_auto_helper(int action, int i0, int i1) { int m = i0; int step = (i0 > i1) ? -1 : 1; int ret = 0; + srand(time(0)); // For faketime incrementing + int cont = 1; while (cont) { union pac_a_mac this_mac; - this_mac.u64 = m; + this_mac.packed_u64 = m; switch (action & ~HELPER_ACTION_MASK) { case HELPER_AP: ; // Empty statement to allow label before declaration ap ap0; - memcpy(ap0.bssid_addr, &this_mac.u8.pos[0], sizeof(ap0.bssid_addr)); + memcpy(ap0.bssid_addr, &this_mac.unpacked.u8[0], sizeof(ap0.bssid_addr)); if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD) - ap_array_insert(ap0); + insert_to_ap_array(ap0); else ap_array_delete(ap0); break; case HELPER_CLIENT: ; // Empty statement to allow label before declaration client client0; - memcpy(client0.bssid_addr, &this_mac.u8.pos[0], sizeof(client0.bssid_addr)); - memcpy(client0.client_addr, &this_mac.u8.pos[0], sizeof(client0.client_addr)); + memcpy(client0.bssid_addr, &this_mac.unpacked.u8[0], sizeof(client0.bssid_addr)); + memcpy(client0.client_addr, &this_mac.unpacked.u8[0], sizeof(client0.client_addr)); if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD) - client_array_insert(client0); + insert_client_to_array(client0); else client_array_delete(client0); break; case HELPER_PROBE_ARRAY: ; // Empty statement to allow label before declaration probe_entry probe0; - memcpy(probe0.bssid_addr, &this_mac.u8.pos[0], sizeof(probe0.bssid_addr)); - memcpy(probe0.client_addr, &this_mac.u8.pos[0], sizeof(probe0.client_addr)); + memcpy(probe0.bssid_addr, &this_mac.unpacked.u8[0], sizeof(probe0.bssid_addr)); + memcpy(probe0.client_addr, &this_mac.unpacked.u8[0], sizeof(probe0.client_addr)); if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD) - probe_array_insert(probe0); + insert_to_array(probe0, true, true, true); // TODO: Check bool flags else probe_array_delete(probe0); break; case HELPER_AUTH_ENTRY: ; // Empty statement to allow label before declaration auth_entry auth_entry0; - memcpy(auth_entry0.bssid_addr, &this_mac.u8.pos[0], sizeof(auth_entry0.bssid_addr)); - memcpy(auth_entry0.client_addr, &this_mac.u8.pos[0], sizeof(auth_entry0.client_addr)); + memcpy(auth_entry0.bssid_addr, &this_mac.unpacked.u8[0], sizeof(auth_entry0.bssid_addr)); + memcpy(auth_entry0.client_addr, &this_mac.unpacked.u8[0], sizeof(auth_entry0.client_addr)); if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD) - denied_req_array_insert(auth_entry0); + insert_to_denied_req_array(auth_entry0, true); // TODO: Check bool flags else denied_req_array_delete(auth_entry0); break; @@ -161,9 +184,67 @@ int array_auto_helper(int action, int i0, int i1) return ret; } -int consume_actions(int argc, char* argv[]); +static int load_u8(uint8_t* v, char* s); +static int load_u8(uint8_t* v, char* s) +{ + int ret = 0; + sscanf(s, "%" SCNu8, v); + return ret; +} -int consume_actions(int argc, char* argv[]) +static int load_u32(uint32_t* v, char* s); +static int load_u32(uint32_t* v, char* s) +{ + int ret = 0; + sscanf(s, "%" SCNu32, v); + return ret; +} + +static int load_int(int* v, char* s); +static int load_int(int* v, char* s) +{ + int ret = 0; + sscanf(s, "%" "d", v); + return ret; +} + +static int load_string(size_t l, char* v, char* s); +static int load_string(size_t l, char* v, char* s) +{ + int ret = 0; + strncpy(v, s, l); + return ret; +} + +static int load_ssid(uint8_t* v, char* s); +static int load_ssid(uint8_t* v, char* s) +{ + int ret = 0; + strncpy((char*)v, s, SSID_MAX_LEN); + return ret; +} + +static int load_time(time_t* v, char* s); +static int load_time(time_t* v, char* s) +{ + int ret = 0; + sscanf(s, "%" "li", v); // TODO: Check making portable for target SoC environemnts? + return ret; +} + +static int load_mac(uint8_t* v, char* s); +static int load_mac(uint8_t* v, char* s) +{ + int ret = 0; + //printf("Loading mac from: %s\n", s); + sscanf(s, "%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":%" SCNx8, &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]); + return ret; +} + + +static int consume_actions(int argc, char* argv[]); + +static int consume_actions(int argc, char* argv[]) { int ret = 0; int args_required = 0; // Suppress compiler warming by assigning initial value @@ -172,14 +253,76 @@ int consume_actions(int argc, char* argv[]) while (curr_arg < argc && ret == 0) { - if (strcmp(*argv, "probe_sort") == 0) + if ((strcmp(*argv, "time") == 0) || (strcmp(*argv, "elapsed") == 0)) // "time" is deprecated to avoid confusion with "faketime" commands + { + struct timespec spec; + double curr_time; + + args_required = 1; + + //TODO: Check portability for SoC devices when benchmarking? + clock_gettime(CLOCK_REALTIME, &spec); + curr_time = spec.tv_sec * 1000.0 + spec.tv_nsec / 1000000.0; + + // First call sets base time for script + // Later calls report elapsed time since base, and from previous call + if (first_time) + { + first_time = false; + base_time = curr_time; + last_time = curr_time; + } + + printf("Elapsed time: base=%fms, last=%fms\n", curr_time - base_time, curr_time - last_time); + + last_time = curr_time; + } + else if (strcmp(*argv, "probe_sort") == 0) { args_required = 2; if (curr_arg + args_required <= argc) { + // sort_string is a datastorage.c global used for sorting probe entries strcpy(sort_string, argv[1]); } } + else if (strcmp(*argv, "faketime") == 0) + { + args_required = 2; + if (curr_arg + args_required <= argc) + { + if (strcmp(*(argv + 1), "auto") == 0) + { + faketime_auto = true; + } + else if (strcmp(*(argv + 1), "show") == 0) + { + printf("FAKETIME is currently: %ld\n", faketime); + } + else + { + args_required = 3; + if (curr_arg + args_required <= argc) + { + if (strcmp(*(argv + 1), "set") == 0) + { + faketime_auto = false; + faketime = atol(argv[2]); + } + else if (strcmp(*(argv + 1), "add") == 0) + { + faketime_auto = false; + faketime += atol(argv[2]); + } + else + { + printf("FAKETIME \"%s\": Unknown or mangled - stopping!\n", *(argv + 1)); + ret = -1; + } + } + } + } + } else if (strcmp(*argv, "ap_show") == 0) { args_required = 1; @@ -272,6 +415,436 @@ int consume_actions(int argc, char* argv[]) ret = array_auto_helper(HELPER_AUTH_ENTRY | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2))); } } + else if (strcmp(*argv, "remove_old_ap_entries") == 0) + { + args_required = 2; + if (curr_arg + args_required <= argc) + { + remove_old_ap_entries(faketime, atol(argv[1])); + } + } + else if (strcmp(*argv, "remove_old_client_entries") == 0) + { + args_required = 2; + if (curr_arg + args_required <= argc) + { + remove_old_client_entries(faketime, atol(argv[1])); + } + } + else if (strcmp(*argv, "remove_old_probe_entries") == 0) + { + args_required = 2; + if (curr_arg + args_required <= argc) + { + remove_old_probe_entries(faketime, atol(argv[1])); + } + } + else if (strcmp(*argv, "dawn") == 0) // Load metrics that configure DAWN + { + args_required = 1; + while (ret == 0 && curr_arg + args_required < argc) + { + char* fn = *(argv + args_required); + + if (!strcmp(fn, "default")) + { + dawn_metric.ap_weight = 0; // Sum component + dawn_metric.ht_support = 10; // Sum component + dawn_metric.vht_support = 100; // Sum component + dawn_metric.no_ht_support = 0; // Sum component + dawn_metric.no_vht_support = 0; // Sum component + dawn_metric.rssi = 10; // Sum component + dawn_metric.low_rssi = -500; // Sum component + dawn_metric.freq = 100; // Sum component + dawn_metric.chan_util = 0; // Sum component + dawn_metric.max_chan_util = -500; // Sum component + dawn_metric.rssi_val = -60; + dawn_metric.low_rssi_val = -80; + dawn_metric.chan_util_val = 140; + dawn_metric.max_chan_util_val = 170; + dawn_metric.min_probe_count = 2; + dawn_metric.bandwidth_threshold = 6; + dawn_metric.use_station_count = 1; + dawn_metric.max_station_diff = 1; + dawn_metric.eval_probe_req = 1; + dawn_metric.eval_auth_req = 1; + dawn_metric.eval_assoc_req = 1; + dawn_metric.deny_auth_reason = 1; + dawn_metric.deny_assoc_reason = 17; + dawn_metric.use_driver_recog = 1; + dawn_metric.min_kick_count = 3; + dawn_metric.chan_util_avg_period = 3; + dawn_metric.set_hostapd_nr = 1; + dawn_metric.kicking = 0; + dawn_metric.op_class = 0; + dawn_metric.duration = 0; + dawn_metric.mode = 0; + dawn_metric.scan_channel = 0; + } + else if (!strncmp(fn, "ap_weight=", 10)) load_int(&dawn_metric.ap_weight, fn + 10); + else if (!strncmp(fn, "ht_support=", 11)) load_int(&dawn_metric.ht_support, fn + 11); + else if (!strncmp(fn, "vht_support=", 12)) load_int(&dawn_metric.vht_support, fn + 12); + else if (!strncmp(fn, "no_ht_support=", 14)) load_int(&dawn_metric.no_ht_support, fn + 14); + else if (!strncmp(fn, "no_vht_support=", 15)) load_int(&dawn_metric.no_vht_support, fn + 15); + else if (!strncmp(fn, "rssi=", 5)) load_int(&dawn_metric.rssi, fn + 5); + else if (!strncmp(fn, "low_rssi=", 9)) load_int(&dawn_metric.low_rssi, fn + 9); + else if (!strncmp(fn, "freq=", 5)) load_int(&dawn_metric.freq, fn + 5); + else if (!strncmp(fn, "chan_util=", 10)) load_int(&dawn_metric.chan_util, fn + 10); + else if (!strncmp(fn, "max_chan_util=", 14)) load_int(&dawn_metric.max_chan_util, fn + 14); + else if (!strncmp(fn, "rssi_val=", 9)) load_int(&dawn_metric.rssi_val, fn + 9); + else if (!strncmp(fn, "low_rssi_val=", 13)) load_int(&dawn_metric.low_rssi_val, fn + 13); + else if (!strncmp(fn, "chan_util_val=", 14)) load_int(&dawn_metric.chan_util_val, fn + 14); + else if (!strncmp(fn, "max_chan_util_val=", 18)) load_int(&dawn_metric.max_chan_util_val, fn + 18); + else if (!strncmp(fn, "min_probe_count=", 16)) load_int(&dawn_metric.min_probe_count, fn + 16); + else if (!strncmp(fn, "bandwidth_threshold=", 20)) load_int(&dawn_metric.bandwidth_threshold, fn + 20); + else if (!strncmp(fn, "use_station_count=", 18)) load_int(&dawn_metric.use_station_count, fn + 18); + else if (!strncmp(fn, "max_station_diff=", 17)) load_int(&dawn_metric.max_station_diff, fn + 17); + else if (!strncmp(fn, "eval_probe_req=", 15)) load_int(&dawn_metric.eval_probe_req, fn + 15); + else if (!strncmp(fn, "eval_auth_req=", 14)) load_int(&dawn_metric.eval_auth_req, fn + 14); + else if (!strncmp(fn, "eval_assoc_req=", 15)) load_int(&dawn_metric.eval_assoc_req, fn + 15); + else if (!strncmp(fn, "deny_auth_reason=", 17)) load_int(&dawn_metric.deny_auth_reason, fn + 17); + else if (!strncmp(fn, "deny_assoc_reason=", 18)) load_int(&dawn_metric.deny_assoc_reason, fn + 18); + else if (!strncmp(fn, "use_driver_recog=", 17)) load_int(&dawn_metric.use_driver_recog, fn + 17); + else if (!strncmp(fn, "min_kick_count=", 15)) load_int(&dawn_metric.min_kick_count, fn + 15); + else if (!strncmp(fn, "chan_util_avg_period=", 21)) load_int(&dawn_metric.chan_util_avg_period, fn + 21); + else if (!strncmp(fn, "set_hostapd_nr=", 15)) load_int(&dawn_metric.set_hostapd_nr, fn + 15); + else if (!strncmp(fn, "kicking=", 8)) load_int(&dawn_metric.kicking, fn + 8); + else if (!strncmp(fn, "op_class=", 9)) load_int(&dawn_metric.op_class, fn + 9); + else if (!strncmp(fn, "duration=", 9)) load_int(&dawn_metric.duration, fn + 9); + else if (!strncmp(fn, "mode=", 5)) load_int(&dawn_metric.mode, fn + 5); + else if (!strncmp(fn, "scan_channel=", 13)) load_int(&dawn_metric.scan_channel, fn + 13); + else { + printf("ERROR: Loading DAWN control metrics, but don't recognise assignment \"%s\"\n", fn); + ret = 1; + } + + if (ret == 0) + args_required++; + } + } + else if (strcmp(*argv, "macadd") == 0) + { + + args_required = 2; + if (curr_arg + args_required <= argc) + { + uint8_t mac0[ETH_ALEN]; + + load_mac(mac0, argv[1]); + insert_to_maclist(mac0); + } + } + else if (strcmp(*argv, "macget") == 0) + { + + args_required = 2; + if (curr_arg + args_required <= argc) + { + uint8_t mac0[ETH_ALEN]; + + load_mac(mac0, argv[1]); + printf("Looking for MAC %s - result %d\n", argv[1], mac_in_maclist(mac0)); + } + } + else if (strcmp(*argv, "ap") == 0) + { + ap ap0; + + memset(ap0.bssid_addr, 0, ETH_ALEN); + ap0.freq = 0; + ap0.ht_support = 0; + ap0.vht_support = 0; + ap0.channel_utilization = 0; + ap0.time = faketime; + ap0.station_count = 0; + memset(ap0.ssid, '*', SSID_MAX_LEN); + ap0.ssid[SSID_MAX_LEN - 1] = '\0'; + ap0.neighbor_report[0] = 0; + ap0.collision_domain = 0; + ap0.bandwidth = 0; + ap0.ap_weight = 0; + + args_required = 1; + while (ret == 0 && curr_arg + args_required < argc) + { + char* fn = *(argv + args_required); + + //TODO: Somehwat hacky parsing of value strings to get us going... + if (false); // Hack to allow easy paste of generated code + else if (!strncmp(fn, "bssid=", 6)) load_mac(ap0.bssid_addr, fn + 6); + else if (!strncmp(fn, "freq=", 5)) load_u32(&ap0.freq, fn + 5); + else if (!strncmp(fn, "ht_sup=", 7)) load_u8(&ap0.ht_support, fn + 7); + else if (!strncmp(fn, "vht_sup=", 8)) load_u8(&ap0.vht_support, fn + 8); + else if (!strncmp(fn, "util=", 5)) load_u32(&ap0.channel_utilization, fn + 5); + else if (!strncmp(fn, "time=", 5)) load_time(&ap0.time, fn + 5); + else if (!strncmp(fn, "stations=", 9)) load_u32(&ap0.station_count, fn + 9); + else if (!strncmp(fn, "ssid=", 5)) load_ssid(ap0.ssid, fn + 5); + else if (!strncmp(fn, "neighbors=", 10)) load_string(NEIGHBOR_REPORT_LEN, ap0.neighbor_report, fn + 10); + else if (!strncmp(fn, "col_d=", 6)) load_u32(&ap0.collision_domain, fn + 6); + else if (!strncmp(fn, "bandwidth=", 10)) load_u32(&ap0.bandwidth, fn + 10); + else if (!strncmp(fn, "weight=", 7)) load_u32(&ap0.ap_weight, fn + 7); + else { + printf("ERROR: Loading AP, but don't recognise assignment \"%s\"\n", fn); + ret = 1; + } + + if (ret == 0) + { + args_required++; + } + } + + if (ret == 0) + { + insert_to_ap_array(ap0); + } + } + else if (strcmp(*argv, "client") == 0) + { + client cl0; + + memset(cl0.bssid_addr, 0, ETH_ALEN); + memset(cl0.client_addr, 0, ETH_ALEN); + memset(cl0.signature, 0, SIGNATURE_LEN); + cl0.ht_supported = 0; + cl0.vht_supported = 0; + cl0.freq = 0; + cl0.auth = 0; + cl0.assoc = 0; + cl0.authorized = 0; + cl0.preauth = 0; + cl0.wds = 0; + cl0.wmm = 0; + cl0.ht = 0; + cl0.vht = 0; + cl0.wps = 0; + cl0.mfp = 0; + cl0.time = faketime; + cl0.aid = 0; + cl0.kick_count = 0; + + args_required = 1; + while (ret == 0 && curr_arg + args_required < argc) + { + char* fn = *(argv + args_required); + + //TODO: Somewhat hacky parsing of value strings to get us going... + if (false); // Hack to allow easy paste of generated code + else if (!strncmp(fn, "bssid=", 6)) load_mac(cl0.bssid_addr, fn + 6); + else if (!strncmp(fn, "client=", 7)) load_mac(cl0.client_addr, fn + 7); + else if (!strncmp(fn, "sig=", 4)) load_string(SIGNATURE_LEN, cl0.signature, fn + 4); + else if (!strncmp(fn, "ht_sup=", 7)) load_u8(&cl0.ht_supported, fn + 7); + else if (!strncmp(fn, "vht_sup=", 8)) load_u8(&cl0.vht_supported, fn + 8); + else if (!strncmp(fn, "freq=", 5)) load_u32(&cl0.freq, fn + 5); + else if (!strncmp(fn, "auth=", 5)) load_u8(&cl0.auth, fn + 5); + else if (!strncmp(fn, "assoc=", 6)) load_u8(&cl0.assoc, fn + 6); + else if (!strncmp(fn, "authz=", 6)) load_u8(&cl0.authorized, fn + 6); + else if (!strncmp(fn, "preauth=", 8)) load_u8(&cl0.preauth, fn + 8); + else if (!strncmp(fn, "wds=", 4)) load_u8(&cl0.wds, fn + 4); + else if (!strncmp(fn, "wmm=", 4)) load_u8(&cl0.wmm, fn + 4); + else if (!strncmp(fn, "ht_cap=", 3)) load_u8(&cl0.ht, fn + 3); + else if (!strncmp(fn, "vht_cap=", 4)) load_u8(&cl0.vht, fn + 4); + else if (!strncmp(fn, "wps=", 4)) load_u8(&cl0.wps, fn + 4); + else if (!strncmp(fn, "mfp=", 4)) load_u8(&cl0.mfp, fn + 4); + else if (!strncmp(fn, "time=", 5)) load_time(&cl0.time, fn + 5); + else if (!strncmp(fn, "aid=", 4)) load_u32(&cl0.aid, fn + 4); + else if (!strncmp(fn, "kick=", 5)) load_u32(&cl0.kick_count, fn + 5); + else { + printf("ERROR: Loading CLIENT, but don't recognise assignment \"%s\"\n", fn); + ret = 1; + } + + if (ret == 0) + args_required++; + } + + if (ret == 0) + { + insert_client_to_array(cl0); + } + } + else if (strcmp(*argv, "probe") == 0) + { + probe_entry pr0; + + memset(pr0.bssid_addr, 0, ETH_ALEN); + memset(pr0.client_addr, 0, ETH_ALEN); + memset(pr0.target_addr, 0, ETH_ALEN); + pr0.signal = 0; + pr0.freq = 0; + pr0.ht_capabilities = 0; + pr0.vht_capabilities = 0; + pr0.time = faketime; + pr0.counter = 0; +#ifndef DAWN_NO_OUTPUT + pr0.deny_counter = 0; + pr0.max_supp_datarate = 0; + pr0.min_supp_datarate = 0; +#endif + pr0.rcpi = 0; + pr0.rsni = 0; + + args_required = 1; + while (ret == 0 && curr_arg + args_required < argc) + { + char* fn = *(argv + args_required); + + //TODO: Somewhat hacky parsing of value strings to get us going... + if (false); // Hack to allow easy paste of generated code + else if (!strncmp(fn, "bssid=", 6)) load_mac(pr0.bssid_addr, fn + 6); + else if (!strncmp(fn, "client=", 7)) load_mac(pr0.client_addr, fn + 7); + else if (!strncmp(fn, "target=", 7)) load_mac(pr0.target_addr, fn + 7); + else if (!strncmp(fn, "signal=", 7)) load_u32(&pr0.signal, fn + 7); + else if (!strncmp(fn, "freq=", 5)) load_u32(&pr0.freq, fn + 5); + else if (!strncmp(fn, "ht_cap=", 7)) load_u8(&pr0.ht_capabilities, fn + 7); + else if (!strncmp(fn, "vht_cap=", 8)) load_u8(&pr0.vht_capabilities, fn + 8); + else if (!strncmp(fn, "time=", 5)) load_time(&pr0.time, fn + 5); + else if (!strncmp(fn, "counter=", 8)) load_int(&pr0.counter, fn + 8); +#ifndef DAWN_NO_OUTPUT + else if (!strncmp(fn, "deny=", 5)) load_int(&pr0.deny_counter, fn + 5); + else if (!strncmp(fn, "max_rate=", 9)) load_u8(&pr0.max_supp_datarate, fn + 9); + else if (!strncmp(fn, "min_rate=", 9)) load_u8(&pr0.min_supp_datarate, fn + 9); +#endif + else if (!strncmp(fn, "rcpi=", 5)) load_u32(&pr0.rcpi, fn + 5); + else if (!strncmp(fn, "rsni=", 5)) load_u32(&pr0.rsni, fn + 5); + else { + printf("ERROR: Loading PROBE, but don't recognise assignment \"%s\"\n", fn); + ret = 1; + } + + if (ret == 0) + args_required++; + } + + if (ret == 0) + { + insert_to_array(pr0, true, true, true); + } + } + else if (strcmp(*argv, "auth_entry") == 0) + { + auth_entry au0; + + memset(au0.bssid_addr, 0, ETH_ALEN); + memset(au0.client_addr, 0, ETH_ALEN); + memset(au0.target_addr, 0, ETH_ALEN); + au0.signal = 0; + au0.freq = 0; + au0.time = faketime; + au0.counter = 0; + + args_required = 1; + while (ret == 0 && curr_arg + args_required < argc) + { + char* fn = *(argv + args_required); + + //TODO: Somewhat hacky parsing of value strings to get us going... + if (false); // Hack to allow easy paste of generated code + else if (!strncmp(fn, "bssid=", 6)) load_mac(au0.bssid_addr, fn + 6); + else if (!strncmp(fn, "client=", 7)) load_mac(au0.client_addr, fn + 7); + else if (!strncmp(fn, "target=", 7)) load_mac(au0.target_addr, fn + 7); + else if (!strncmp(fn, "signal=", 7)) load_u32(&au0.signal, fn + 7); + else if (!strncmp(fn, "freq=", 5)) load_u32(&au0.freq, fn + 5); + else if (!strncmp(fn, "time=", 5)) load_time(&au0.time, fn + 5); + else if (!strncmp(fn, "counter=", 8)) load_int(&au0.counter, fn + 8); + else { + printf("ERROR: Loading AUTH, but don't recognise assignment \"%s\"\n", fn); + ret = 1; + } + + if (ret == 0) + args_required++; + } + + if (ret == 0) + { + insert_to_denied_req_array(au0, true); + } + } + else if (strcmp(*argv, "kick") == 0) // Perform kicking evaluation + { + args_required = 3; + if (curr_arg + args_required <= argc) + { + int safety_count = 1000; + + uint32_t kick_id; + uint8_t kick_mac[ETH_ALEN]; + + load_mac(kick_mac, argv[1]); + load_u32(&kick_id, argv[2]); + + while ((kick_clients(kick_mac, kick_id) != 0) && safety_count--); + } + } + else if (strcmp(*argv, "better_ap_available") == 0) + { + args_required = 4; + if (curr_arg + args_required <= argc) + { + uint8_t bssid_mac[ETH_ALEN]; + uint8_t client_mac[ETH_ALEN]; + uint32_t autokick; + + int tr = 9999; // Tamper evident value + + load_mac(bssid_mac, argv[1]); + load_mac(client_mac, argv[2]); + load_u32(&autokick, argv[3]); + + char nb[NEIGHBOR_REPORT_LEN] = "TAMPER EVIDENT NEIGHBOR REPORT INITIALISATION STRING"; + + if (curr_arg + 5 <= argc) + { + args_required = 5; + + if (strcmp(argv[4], "\0") == 0) // Provide a way to set an empty string + { + strcpy(nb, ""); + } + else + { + strcpy(nb, argv[4]); + } + + tr = better_ap_available(bssid_mac, client_mac, nb, autokick); + } + else + { + tr = better_ap_available(bssid_mac, client_mac, NULL, autokick); + } + + printf("better_ap_available returned %d (with neighbour report %s)\n", tr, nb); + } + } + else if (strcmp(*argv, "eval_probe_metric") == 0) + { + args_required = 3; + if (curr_arg + args_required <= argc) + { + uint8_t bssid_mac[ETH_ALEN]; + uint8_t client_mac[ETH_ALEN]; + + load_mac(bssid_mac, argv[1]); + load_mac(client_mac, argv[2]); + + probe_entry probe0 = probe_array_get_entry(bssid_mac, client_mac); + + union pac_a_mac test_mac; + memcpy(test_mac.unpacked.u8, probe0.bssid_addr, sizeof(probe0.bssid_addr)); + + if ((test_mac.packed_u64 & MAC_MASK_PACKED_U64) == 0 ) + { + printf("eval_probe_metric: Can't find probe entry!\n"); + } + else + { + int this_metric = eval_probe_metric(probe0); + printf("eval_probe_metric: Returned %d\n", this_metric); + } + + } + } else { args_required = 1; @@ -285,6 +858,17 @@ int consume_actions(int argc, char* argv[]) { // Still need to continue consuming args argv += args_required; + + // Sometimes move fake time on a second - about 1 in 5 chance + if (faketime_auto && ((rand() & 0xFF) > 200)) + { + faketime += 1; + + if (!(faketime & 1)) + printf("Faketime: tick %ld...\n", faketime); + else + printf("Faketime: tock %ld...\n", faketime); + } } else { @@ -297,26 +881,29 @@ int consume_actions(int argc, char* argv[]) return ret; } -int process_script_line(char* line, size_t len); -#define MAX_LINE_ARGS 5 -int process_script_line(char* line, size_t len) +#define MAX_LINE_ARGS 20 +static int process_script_line(char* line, size_t len); +static int process_script_line(char* line, size_t len) { int argc = 0; char* argv[MAX_LINE_ARGS]; bool in_white = true; - bool force_blank = false; - + bool force_nul = false; + int ret = 0; //printf("%lu: \"%s\"\n", len, line); while (len > 0 && !ret) { - if (isblank(*line) || (*line == '\n') || (*line == '\r') || (*line == '#') || force_blank) + if (isblank(*line) || (*line == '\n') || (*line == '\r') || (*line == '#') || force_nul) { if (*line == '#') { //printf("Blanking 0x%02X...\n", *line); - force_blank = true; + force_nul = true; + + // Untested - might bring parsing to faster end... + // len = 1; } //printf("Zapping 0x%02X...\n", *line); @@ -355,7 +942,7 @@ int process_script_line(char* line, size_t len) int main(int argc, char* argv[]) { - FILE* fp; + FILE* fp = NULL; char* line = NULL; size_t len = 0; ssize_t read; @@ -377,6 +964,9 @@ int main(int argc, char* argv[]) } else { + strcpy(sort_string, "bcfs"); + init_mutex(); + // Step past command name on args, ie argv[0] argc--; argv++; @@ -422,11 +1012,17 @@ int main(int argc, char* argv[]) read = getline(&line, &len, fp); } - if (fp != stdin) + if (fp && fp != stdin) + { fclose(fp); + fp = NULL; + } if (line) + { free(line); + line = NULL; + } } argc--; @@ -438,6 +1034,8 @@ int main(int argc, char* argv[]) // Take direct input on command line ret = consume_actions(argc, argv); } + + destroy_mutex(); } printf("\nDAWN datastorage.c test harness - finshed. \n"); diff --git a/src/utils/dawn_iwinfo.c b/src/utils/dawn_iwinfo.c index 2d7a45d..905f518 100644 --- a/src/utils/dawn_iwinfo.c +++ b/src/utils/dawn_iwinfo.c @@ -1,14 +1,14 @@ +#include +#include + +#include "mac_utils.h" +#include "datastorage.h" #include "dawn_iwinfo.h" -#include -#include -#include - -#include "utils.h" -#include "ubus.h" - #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +char hostapd_dir_glob[HOSTAPD_DIR_LEN]; + int call_iwinfo(char *client_addr); int parse_rssi(char *iwinfo_string); @@ -271,7 +271,7 @@ int get_bssid(const char *ifname, uint8_t *bssid_addr) { return 0; } -int get_ssid(const char *ifname, char* ssid) { +int get_ssid(const char *ifname, char* ssid, size_t ssidmax) { const struct iwinfo_ops *iw; char buf[IWINFO_ESSID_MAX_SIZE+1] = { 0 }; if (strcmp(ifname, "global") == 0) @@ -280,7 +280,7 @@ int get_ssid(const char *ifname, char* ssid) { if (iw->ssid(ifname, buf)) memset(buf, 0, sizeof(buf)); - memcpy(ssid, buf, (SSID_MAX_LEN) * sizeof(char)); + memcpy(ssid, buf, ssidmax); strcpy(ssid, buf); iwinfo_finish(); return 0; @@ -373,6 +373,7 @@ int support_vht(const char *ifname) { return 0; } + // TODO: 1 << 2 duplicated here, and also appears as HT mode mask uint32_t vht_support_bitmask = (1 << 2) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6); int ret = htmodes & vht_support_bitmask ? 1 : 0; iwinfo_finish(); diff --git a/src/utils/dawn_uci.c b/src/utils/dawn_uci.c index 15e1cf2..e8fb7eb 100644 --- a/src/utils/dawn_uci.c +++ b/src/utils/dawn_uci.c @@ -1,8 +1,9 @@ #include #include -#include -#include +#include +#include "datastorage.h" +#include "dawn_iwinfo.h" #include "dawn_uci.h" diff --git a/src/utils/ieee80211_utils.c b/src/utils/ieee80211_utils.c index 21c13fc..bf2ddcb 100644 --- a/src/utils/ieee80211_utils.c +++ b/src/utils/ieee80211_utils.c @@ -1,11 +1,14 @@ #include "ieee80211_utils.h" -#include - double iee80211_calculate_bitrate(uint8_t supp_rate_val) { return ((double) supp_rate_val) / 2; } double iee80211_calculate_expected_throughput_mbit(int exp_thr) { return (((double) exp_thr) / 1000); -} \ No newline at end of file +} + +int rcpi_to_rssi(int rcpi) +{ + return rcpi / 2 - 110; +} diff --git a/src/utils/mac_utils.c b/src/utils/mac_utils.c new file mode 100644 index 0000000..ec52b9f --- /dev/null +++ b/src/utils/mac_utils.c @@ -0,0 +1,83 @@ +#include +#include +#include + +#include "utils.h" +#include "mac_utils.h" + +// based on: hostapd src/utils/common.c +int hwaddr_aton(const char* txt, uint8_t* addr) { + int i; + + for (i = 0; i < ETH_ALEN; i++) { + int a, b; + + a = hex_to_dec(*txt++); + if (a < 0) return -1; + b = hex_to_dec(*txt++); + if (b < 0) return -1; + *addr++ = (a << 4) | b; + // TODO: Should NUL terminator be checked for? Is aa:bb:cc:dd:ee:ff00 valid input? + if (i < (ETH_ALEN - 1) && *txt++ != ':') return -1; + } + + return 0; +} + +int mac_is_equal(const uint8_t addr1[], const uint8_t addr2[]) { + return memcmp(addr1, addr2, ETH_ALEN * sizeof(uint8_t)) == 0; +} + +int mac_is_greater(const uint8_t addr1[], const uint8_t addr2[]) { + for (int i = 0; i < ETH_ALEN; i++) { + if (addr1[i] > addr2[i]) { + return 1; + } + if (addr1[i] < addr2[i]) { + return 0; + } + + // if equal continue... + } + return 0; +} +// TODO: Never called in DAWN code. Remove? +#if 0 +/* Convert badly formed MAC addresses with single digit element to double digit +** eg 11:2:33:4:55:6 to 11:02:33:04:55:06 */` +int convert_mac(char* in, char* out) { + int i, j = 0; + + for (i = 0; i < ETH_ALEN; i++) { + /* Do we have a single-digit element? */ + if (in[j + 1] == ':' || in[j + 1] == '\0') { + out[3 * i] = '0'; + out[(3 * i) + 1] = toupper(in[j]); + out[(3 * i) + 2] = toupper(in[j + 1]); + j += 2; + } + else { + out[3 * i] = toupper(in[j]); + out[(3 * i) + 1] = toupper(in[j + 1]); + out[(3 * i) + 2] = in[j + 2]; + j += 3; + } + } + return 0; +} +#endif + +void write_mac_to_file(char* path, uint8_t addr[]) { + FILE* f = fopen(path, "a"); + if (f == NULL) { + fprintf(stderr, "Error opening mac file!\n"); + exit(1); + } + + char mac_buf[20]; + sprintf(mac_buf, MACSTR, MAC2STR(addr)); + + fprintf(f, "%s\n", mac_buf); + + fclose(f); +} diff --git a/src/utils/msghandler.c b/src/utils/msghandler.c new file mode 100644 index 0000000..140648e --- /dev/null +++ b/src/utils/msghandler.c @@ -0,0 +1,792 @@ +#include + +#include "dawn_uci.h" +#include "datastorage.h" +#include "ubus.h" +#include "msghandler.h" + + +static struct blob_buf network_buf; +static struct blob_buf data_buf; + +enum { + NETWORK_METHOD, + NETWORK_DATA, + __NETWORK_MAX, +}; + +static const struct blobmsg_policy network_policy[__NETWORK_MAX] = { + [NETWORK_METHOD] = {.name = "method", .type = BLOBMSG_TYPE_STRING}, + [NETWORK_DATA] = {.name = "data", .type = BLOBMSG_TYPE_STRING}, +}; + +enum { + HOSTAPD_NOTIFY_BSSID_ADDR, + HOSTAPD_NOTIFY_CLIENT_ADDR, + __HOSTAPD_NOTIFY_MAX, +}; + +static const struct blobmsg_policy hostapd_notify_policy[__HOSTAPD_NOTIFY_MAX] = { + [HOSTAPD_NOTIFY_BSSID_ADDR] = {.name = "bssid", .type = BLOBMSG_TYPE_STRING}, + [HOSTAPD_NOTIFY_CLIENT_ADDR] = {.name = "address", .type = BLOBMSG_TYPE_STRING}, +}; + +enum { + PROB_BSSID_ADDR, + PROB_CLIENT_ADDR, + PROB_TARGET_ADDR, + PROB_SIGNAL, + PROB_FREQ, + PROB_HT_CAPABILITIES, + PROB_VHT_CAPABILITIES, + PROB_RCPI, + PROB_RSNI, + __PROB_MAX, +}; + +static const struct blobmsg_policy prob_policy[__PROB_MAX] = { + [PROB_BSSID_ADDR] = {.name = "bssid", .type = BLOBMSG_TYPE_STRING}, + [PROB_CLIENT_ADDR] = {.name = "address", .type = BLOBMSG_TYPE_STRING}, + [PROB_TARGET_ADDR] = {.name = "target", .type = BLOBMSG_TYPE_STRING}, + [PROB_SIGNAL] = {.name = "signal", .type = BLOBMSG_TYPE_INT32}, + [PROB_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, + [PROB_HT_CAPABILITIES] = {.name = "ht_capabilities", .type = BLOBMSG_TYPE_TABLE}, + [PROB_VHT_CAPABILITIES] = {.name = "vht_capabilities", .type = BLOBMSG_TYPE_TABLE}, + [PROB_RCPI] = {.name = "rcpi", .type = BLOBMSG_TYPE_INT32}, + [PROB_RSNI] = {.name = "rsni", .type = BLOBMSG_TYPE_INT32}, +}; + +enum { + CLIENT_TABLE, + CLIENT_TABLE_BSSID, + CLIENT_TABLE_SSID, + CLIENT_TABLE_FREQ, + CLIENT_TABLE_HT, + CLIENT_TABLE_VHT, + CLIENT_TABLE_CHAN_UTIL, + CLIENT_TABLE_NUM_STA, + CLIENT_TABLE_COL_DOMAIN, + CLIENT_TABLE_BANDWIDTH, + CLIENT_TABLE_WEIGHT, + CLIENT_TABLE_NEIGHBOR, + CLIENT_TABLE_IFACE, + CLIENT_TABLE_HOSTNAME, + __CLIENT_TABLE_MAX, +}; + +static const struct blobmsg_policy client_table_policy[__CLIENT_TABLE_MAX] = { + [CLIENT_TABLE] = {.name = "clients", .type = BLOBMSG_TYPE_TABLE}, + [CLIENT_TABLE_BSSID] = {.name = "bssid", .type = BLOBMSG_TYPE_STRING}, + [CLIENT_TABLE_SSID] = {.name = "ssid", .type = BLOBMSG_TYPE_STRING}, + [CLIENT_TABLE_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, + [CLIENT_TABLE_HT] = {.name = "ht_supported", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_TABLE_VHT] = {.name = "vht_supported", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_TABLE_CHAN_UTIL] = {.name = "channel_utilization", .type = BLOBMSG_TYPE_INT32}, + [CLIENT_TABLE_NUM_STA] = {.name = "num_sta", .type = BLOBMSG_TYPE_INT32}, + [CLIENT_TABLE_COL_DOMAIN] = {.name = "collision_domain", .type = BLOBMSG_TYPE_INT32}, + [CLIENT_TABLE_BANDWIDTH] = {.name = "bandwidth", .type = BLOBMSG_TYPE_INT32}, + [CLIENT_TABLE_WEIGHT] = {.name = "ap_weight", .type = BLOBMSG_TYPE_INT32}, + [CLIENT_TABLE_NEIGHBOR] = {.name = "neighbor_report", .type = BLOBMSG_TYPE_STRING}, + [CLIENT_TABLE_IFACE] = {.name = "iface", .type = BLOBMSG_TYPE_STRING}, + [CLIENT_TABLE_HOSTNAME] = {.name = "hostname", .type = BLOBMSG_TYPE_STRING}, +}; + +enum { + CLIENT_SIGNATURE, + CLIENT_AUTH, + CLIENT_ASSOC, + CLIENT_AUTHORIZED, + CLIENT_PREAUTH, + CLIENT_WDS, + CLIENT_WMM, + CLIENT_HT, + CLIENT_VHT, + CLIENT_WPS, + CLIENT_MFP, + CLIENT_AID, + CLIENT_RRM, + __CLIENT_MAX, +}; + +static const struct blobmsg_policy client_policy[__CLIENT_MAX] = { + [CLIENT_SIGNATURE] = {.name = "signature", .type = BLOBMSG_TYPE_STRING}, + [CLIENT_AUTH] = {.name = "auth", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_ASSOC] = {.name = "assoc", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_AUTHORIZED] = {.name = "authorized", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_PREAUTH] = {.name = "preauth", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_WDS] = {.name = "wds", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_WMM] = {.name = "wmm", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_HT] = {.name = "ht", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_VHT] = {.name = "vht", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_WPS] = {.name = "wps", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_MFP] = {.name = "mfp", .type = BLOBMSG_TYPE_INT8}, + [CLIENT_AID] = {.name = "aid", .type = BLOBMSG_TYPE_INT32}, + [CLIENT_RRM] = {.name = "rrm", .type = BLOBMSG_TYPE_ARRAY}, +}; + +static int handle_set_probe(struct blob_attr* msg); + +static int handle_uci_config(struct blob_attr* msg); + + +int parse_to_hostapd_notify(struct blob_attr* msg, hostapd_notify_entry* notify_req) { + struct blob_attr* tb[__HOSTAPD_NOTIFY_MAX]; + + blobmsg_parse(hostapd_notify_policy, __HOSTAPD_NOTIFY_MAX, tb, blob_data(msg), blob_len(msg)); + + if (hwaddr_aton(blobmsg_data(tb[HOSTAPD_NOTIFY_BSSID_ADDR]), notify_req->bssid_addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (hwaddr_aton(blobmsg_data(tb[HOSTAPD_NOTIFY_CLIENT_ADDR]), notify_req->client_addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + return 0; +} + +int parse_to_probe_req(struct blob_attr* msg, probe_entry* prob_req) { + struct blob_attr* tb[__PROB_MAX]; + + blobmsg_parse(prob_policy, __PROB_MAX, tb, blob_data(msg), blob_len(msg)); + + if (hwaddr_aton(blobmsg_data(tb[PROB_BSSID_ADDR]), prob_req->bssid_addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (hwaddr_aton(blobmsg_data(tb[PROB_CLIENT_ADDR]), prob_req->client_addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (hwaddr_aton(blobmsg_data(tb[PROB_TARGET_ADDR]), prob_req->target_addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[PROB_SIGNAL]) { + prob_req->signal = blobmsg_get_u32(tb[PROB_SIGNAL]); + } + + if (tb[PROB_FREQ]) { + prob_req->freq = blobmsg_get_u32(tb[PROB_FREQ]); + } + + if (tb[PROB_RCPI]) { + prob_req->rcpi = blobmsg_get_u32(tb[PROB_RCPI]); + } + else { + prob_req->rcpi = -1; + } + + if (tb[PROB_RSNI]) { + prob_req->rsni = blobmsg_get_u32(tb[PROB_RSNI]); + } + else { + prob_req->rsni = -1; + } + + if (tb[PROB_HT_CAPABILITIES]) { + prob_req->ht_capabilities = true; + } + else + { + prob_req->ht_capabilities = false; + } + + if (tb[PROB_VHT_CAPABILITIES]) { + prob_req->vht_capabilities = true; + } + else + { + prob_req->vht_capabilities = false; + } + + return 0; +} + +int handle_deauth_req(struct blob_attr* msg) { + + hostapd_notify_entry notify_req; + parse_to_hostapd_notify(msg, ¬ify_req); + + client client_entry; + memcpy(client_entry.bssid_addr, notify_req.bssid_addr, sizeof(uint8_t) * ETH_ALEN); + memcpy(client_entry.client_addr, notify_req.client_addr, sizeof(uint8_t) * ETH_ALEN); + + pthread_mutex_lock(&client_array_mutex); + client_array_delete(client_entry); + pthread_mutex_unlock(&client_array_mutex); + + printf("[WC] Deauth: %s\n", "deauth"); + + return 0; +} + +static int handle_set_probe(struct blob_attr* msg) { + + hostapd_notify_entry notify_req; + parse_to_hostapd_notify(msg, ¬ify_req); + + // TODO: Is a client struct needed nere, ir just a uint8[ETH_ALEN]? + client client_entry; + memcpy(client_entry.bssid_addr, notify_req.bssid_addr, sizeof(uint8_t) * ETH_ALEN); + memcpy(client_entry.client_addr, notify_req.client_addr, sizeof(uint8_t) * ETH_ALEN); + + probe_array_set_all_probe_count(client_entry.client_addr, dawn_metric.min_probe_count); + + return 0; +} + +int handle_network_msg(char* msg) { + struct blob_attr* tb[__NETWORK_MAX]; + char* method; + char* data; + + blob_buf_init(&network_buf, 0); + blobmsg_add_json_from_string(&network_buf, msg); + + blobmsg_parse(network_policy, __NETWORK_MAX, tb, blob_data(network_buf.head), blob_len(network_buf.head)); + + if (!tb[NETWORK_METHOD] || !tb[NETWORK_DATA]) { + return -1; + } + + method = blobmsg_data(tb[NETWORK_METHOD]); + data = blobmsg_data(tb[NETWORK_DATA]); + + printf("Network Method new: %s : %s\n", method, msg); + + blob_buf_init(&data_buf, 0); + blobmsg_add_json_from_string(&data_buf, data); + + if (!data_buf.head) { + return -1; + } + + if (blob_len(data_buf.head) <= 0) { + return -1; + } + + if (strlen(method) < 2) { + return -1; + } + + // add inactive death... + +// TODO: strncmp() look wrong - should all tests be for n = 5 characters? Shorthand checks? + if (strncmp(method, "probe", 5) == 0) { + probe_entry entry; + if (parse_to_probe_req(data_buf.head, &entry) == 0) { + entry.time = time(0); + insert_to_array(entry, 0, false, false); // use 802.11k values // TODO: Change 0 to false? + } + } + else if (strncmp(method, "clients", 5) == 0) { + parse_to_clients(data_buf.head, 0, 0); + } + else if (strncmp(method, "deauth", 5) == 0) { + printf("METHOD DEAUTH\n"); + handle_deauth_req(data_buf.head); + } + else if (strncmp(method, "setprobe", 5) == 0) { + printf("HANDLING SET PROBE!\n"); + handle_set_probe(data_buf.head); + } + else if (strncmp(method, "addmac", 5) == 0) { + parse_add_mac_to_file(data_buf.head); + } + else if (strncmp(method, "macfile", 5) == 0) { + parse_add_mac_to_file(data_buf.head); + } + else if (strncmp(method, "uci", 2) == 0) { + printf("HANDLING UCI!\n"); + handle_uci_config(data_buf.head); + } + else if (strncmp(method, "beacon-report", 12) == 0) { + // TODO: Check beacon report stuff + + //printf("HANDLING BEACON REPORT NETWORK!\n"); + //printf("The Method for beacon-report is: %s\n", method); + // ignore beacon reports send via network!, use probe functions for it + //probe_entry entry; // for now just stay at probe entry stuff... + //parse_to_beacon_rep(data_buf.head, &entry, true); + } + else + { + printf("No method fonud for: %s\n", method); + } + + return 0; +} + +static uint8_t dump_rrm_data(void* data, int len, int type) //modify from examples/blobmsg-example.c in libubox +{ + uint32_t ret = 0; + switch (type) { + case BLOBMSG_TYPE_INT32: + ret = *(uint32_t*)data; + break; + default: + fprintf(stderr, "wrong type of rrm array\n"); + } + return (uint8_t)ret; +} + +static uint8_t +dump_rrm_table(struct blob_attr* head, int len) //modify from examples/blobmsg-example.c in libubox +{ + struct blob_attr* attr; + uint8_t ret = 0; + + __blob_for_each_attr(attr, head, len) { + ret = dump_rrm_data(blobmsg_data(attr), blobmsg_data_len(attr), blob_id(attr)); + return ret;// get the first rrm byte + } + return ret; +} + +// TOOD: Refactor this! +static void +dump_client(struct blob_attr** tb, uint8_t client_addr[], const char* bssid_addr, uint32_t freq, uint8_t ht_supported, + uint8_t vht_supported) { + client client_entry; + + hwaddr_aton(bssid_addr, client_entry.bssid_addr); + memcpy(client_entry.client_addr, client_addr, ETH_ALEN * sizeof(uint8_t)); + client_entry.freq = freq; + client_entry.ht_supported = ht_supported; + client_entry.vht_supported = vht_supported; + + if (tb[CLIENT_AUTH]) { + client_entry.auth = blobmsg_get_u8(tb[CLIENT_AUTH]); + } + if (tb[CLIENT_ASSOC]) { + client_entry.assoc = blobmsg_get_u8(tb[CLIENT_ASSOC]); + } + if (tb[CLIENT_AUTHORIZED]) { + client_entry.authorized = blobmsg_get_u8(tb[CLIENT_AUTHORIZED]); + } + if (tb[CLIENT_PREAUTH]) { + client_entry.preauth = blobmsg_get_u8(tb[CLIENT_PREAUTH]); + } + if (tb[CLIENT_WDS]) { + client_entry.wds = blobmsg_get_u8(tb[CLIENT_WDS]); + } + if (tb[CLIENT_WMM]) { + client_entry.wmm = blobmsg_get_u8(tb[CLIENT_WMM]); + } + if (tb[CLIENT_HT]) { + client_entry.ht = blobmsg_get_u8(tb[CLIENT_HT]); + } + if (tb[CLIENT_VHT]) { + client_entry.vht = blobmsg_get_u8(tb[CLIENT_VHT]); + } + if (tb[CLIENT_WPS]) { + client_entry.wps = blobmsg_get_u8(tb[CLIENT_WPS]); + } + if (tb[CLIENT_MFP]) { + client_entry.mfp = blobmsg_get_u8(tb[CLIENT_MFP]); + } + if (tb[CLIENT_AID]) { + client_entry.aid = blobmsg_get_u32(tb[CLIENT_AID]); + } + /* RRM Caps */ + if (tb[CLIENT_RRM]) { + client_entry.rrm_enabled_capa = dump_rrm_table(blobmsg_data(tb[CLIENT_RRM]), + blobmsg_data_len(tb[CLIENT_RRM]));// get the first byte from rrm array +//ap_entry.ap_weight = blobmsg_get_u32(tb[CLIENT_TABLE_RRM]); + } + else { + client_entry.rrm_enabled_capa = 0; + //ap_entry.ap_weight = 0; + } + + // copy signature + if (tb[CLIENT_SIGNATURE]) { + strncpy(client_entry.signature, blobmsg_data(tb[CLIENT_SIGNATURE]), SIGNATURE_LEN * sizeof(char)); + } + else + { + memset(client_entry.signature, 0, 1024); + } + + client_entry.time = time(0); + insert_client_to_array(client_entry); +} + +static int +dump_client_table(struct blob_attr* head, int len, const char* bssid_addr, uint32_t freq, uint8_t ht_supported, + uint8_t vht_supported) { + struct blob_attr* attr; + struct blobmsg_hdr* hdr; + int station_count = 0; + + __blob_for_each_attr(attr, head, len) + { + hdr = blob_data(attr); + + struct blob_attr* tb[__CLIENT_MAX]; + blobmsg_parse(client_policy, __CLIENT_MAX, tb, blobmsg_data(attr), blobmsg_len(attr)); + //char* str = blobmsg_format_json_indent(attr, true, -1); + + int tmp_int_mac[ETH_ALEN]; + uint8_t tmp_mac[ETH_ALEN]; + sscanf((char*)hdr->name, MACSTR, STR2MAC(tmp_int_mac)); + for (int i = 0; i < ETH_ALEN; ++i) + tmp_mac[i] = (uint8_t)tmp_int_mac[i]; + + dump_client(tb, tmp_mac, bssid_addr, freq, ht_supported, vht_supported); + station_count++; + } + return station_count; +} + +int parse_to_clients(struct blob_attr* msg, int do_kick, uint32_t id) { + struct blob_attr* tb[__CLIENT_TABLE_MAX]; + + if (!msg) { + return -1; + } + + if (!blob_data(msg)) { + return -1; + } + + if (blob_len(msg) <= 0) { + return -1; + } + + blobmsg_parse(client_table_policy, __CLIENT_TABLE_MAX, tb, blob_data(msg), blob_len(msg)); + + if (tb[CLIENT_TABLE] && tb[CLIENT_TABLE_BSSID] && tb[CLIENT_TABLE_FREQ]) { + int num_stations = 0; + num_stations = dump_client_table(blobmsg_data(tb[CLIENT_TABLE]), blobmsg_data_len(tb[CLIENT_TABLE]), + blobmsg_data(tb[CLIENT_TABLE_BSSID]), blobmsg_get_u32(tb[CLIENT_TABLE_FREQ]), + blobmsg_get_u8(tb[CLIENT_TABLE_HT]), blobmsg_get_u8(tb[CLIENT_TABLE_VHT])); + ap ap_entry; + hwaddr_aton(blobmsg_data(tb[CLIENT_TABLE_BSSID]), ap_entry.bssid_addr); + ap_entry.freq = blobmsg_get_u32(tb[CLIENT_TABLE_FREQ]); + + if (tb[CLIENT_TABLE_HT]) { + ap_entry.ht_support = blobmsg_get_u8(tb[CLIENT_TABLE_HT]); + } + else { + ap_entry.ht_support = false; + } + + if (tb[CLIENT_TABLE_VHT]) { + ap_entry.vht_support = blobmsg_get_u8(tb[CLIENT_TABLE_VHT]); + } + else + { + ap_entry.vht_support = false; + } + + if (tb[CLIENT_TABLE_CHAN_UTIL]) { + ap_entry.channel_utilization = blobmsg_get_u32(tb[CLIENT_TABLE_CHAN_UTIL]); + } + else // if this is not existing set to 0? //TODO: Consider setting to a value that will not mislead eval_probe_metric(), eg dawn_metric.chan_util_val? + { + ap_entry.channel_utilization = 0; + } + + if (tb[CLIENT_TABLE_SSID]) { + strcpy((char*)ap_entry.ssid, blobmsg_get_string(tb[CLIENT_TABLE_SSID])); + } + + if (tb[CLIENT_TABLE_COL_DOMAIN]) { + ap_entry.collision_domain = blobmsg_get_u32(tb[CLIENT_TABLE_COL_DOMAIN]); + } + else { + ap_entry.collision_domain = -1; + } + + if (tb[CLIENT_TABLE_BANDWIDTH]) { + ap_entry.bandwidth = blobmsg_get_u32(tb[CLIENT_TABLE_BANDWIDTH]); + } + else { + ap_entry.bandwidth = -1; + } + + ap_entry.station_count = num_stations; + + if (tb[CLIENT_TABLE_WEIGHT]) { + ap_entry.ap_weight = blobmsg_get_u32(tb[CLIENT_TABLE_WEIGHT]); + } + else { + ap_entry.ap_weight = 0; + } + + + if (tb[CLIENT_TABLE_NEIGHBOR]) { + strncpy(ap_entry.neighbor_report, blobmsg_get_string(tb[CLIENT_TABLE_NEIGHBOR]), NEIGHBOR_REPORT_LEN); + } + else { + ap_entry.neighbor_report[0] = '\0'; + } + + if (tb[CLIENT_TABLE_IFACE]) { + strncpy(ap_entry.iface, blobmsg_get_string(tb[CLIENT_TABLE_IFACE]), MAX_INTERFACE_NAME); + } + else { + ap_entry.iface[0] = '\0'; + } + + if (tb[CLIENT_TABLE_HOSTNAME]) { + strncpy(ap_entry.hostname, blobmsg_get_string(tb[CLIENT_TABLE_HOSTNAME]), HOST_NAME_MAX); + } + else { + ap_entry.hostname[0] = '\0'; + } + + ap_entry.time = time(0); + insert_to_ap_array(ap_entry); + + if (do_kick && dawn_metric.kicking) { + update_iw_info(ap_entry.bssid_addr); + kick_clients(ap_entry.bssid_addr, id); + } + } + return 0; +} + +enum { + UCI_TABLE_METRIC, + UCI_TABLE_TIMES, + __UCI_TABLE_MAX +}; + +enum { + UCI_HT_SUPPORT, + UCI_VHT_SUPPORT, + UCI_NO_HT_SUPPORT, + UCI_NO_VHT_SUPPORT, + UCI_RSSI, + UCI_LOW_RSSI, + UCI_FREQ, + UCI_CHAN_UTIL, + UCI_MAX_CHAN_UTIL, + UCI_RSSI_VAL, + UCI_LOW_RSSI_VAL, + UCI_CHAN_UTIL_VAL, + UCI_MAX_CHAN_UTIL_VAL, + UCI_MIN_PROBE_COUNT, + UCI_BANDWIDTH_THRESHOLD, + UCI_USE_STATION_COUNT, + UCI_MAX_STATION_DIFF, + UCI_EVAL_PROBE_REQ, + UCI_EVAL_AUTH_REQ, + UCI_EVAL_ASSOC_REQ, + UCI_KICKING, + UCI_DENY_AUTH_REASON, + UCI_DENY_ASSOC_REASON, + UCI_USE_DRIVER_RECOG, + UCI_MIN_NUMBER_TO_KICK, + UCI_CHAN_UTIL_AVG_PERIOD, + UCI_SET_HOSTAPD_NR, + UCI_OP_CLASS, + UCI_DURATION, + UCI_MODE, + UCI_SCAN_CHANNEL, + __UCI_METIC_MAX +}; + +enum { + UCI_UPDATE_CLIENT, + UCI_DENIED_REQ_THRESHOLD, + UCI_REMOVE_CLIENT, + UCI_REMOVE_PROBE, + UCI_REMOVE_AP, + UCI_UPDATE_HOSTAPD, + UCI_UPDATE_TCP_CON, + UCI_UPDATE_CHAN_UTIL, + UCI_UPDATE_BEACON_REPORTS, + __UCI_TIMES_MAX, +}; + +static const struct blobmsg_policy uci_table_policy[__UCI_TABLE_MAX] = { + [UCI_TABLE_METRIC] = {.name = "metric", .type = BLOBMSG_TYPE_TABLE}, + [UCI_TABLE_TIMES] = {.name = "times", .type = BLOBMSG_TYPE_TABLE} +}; + +static const struct blobmsg_policy uci_metric_policy[__UCI_METIC_MAX] = { + [UCI_HT_SUPPORT] = {.name = "ht_support", .type = BLOBMSG_TYPE_INT32}, + [UCI_VHT_SUPPORT] = {.name = "vht_support", .type = BLOBMSG_TYPE_INT32}, + [UCI_NO_HT_SUPPORT] = {.name = "no_ht_support", .type = BLOBMSG_TYPE_INT32}, + [UCI_NO_VHT_SUPPORT] = {.name = "no_vht_support", .type = BLOBMSG_TYPE_INT32}, + [UCI_RSSI] = {.name = "rssi", .type = BLOBMSG_TYPE_INT32}, + [UCI_LOW_RSSI] = {.name = "low_rssi", .type = BLOBMSG_TYPE_INT32}, + [UCI_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, + [UCI_CHAN_UTIL] = {.name = "chan_util", .type = BLOBMSG_TYPE_INT32}, + [UCI_MAX_CHAN_UTIL] = {.name = "max_chan_util", .type = BLOBMSG_TYPE_INT32}, + [UCI_RSSI_VAL] = {.name = "rssi_val", .type = BLOBMSG_TYPE_INT32}, + [UCI_LOW_RSSI_VAL] = {.name = "low_rssi_val", .type = BLOBMSG_TYPE_INT32}, + [UCI_CHAN_UTIL_VAL] = {.name = "chan_util_val", .type = BLOBMSG_TYPE_INT32}, + [UCI_MAX_CHAN_UTIL_VAL] = {.name = "max_chan_util_val", .type = BLOBMSG_TYPE_INT32}, + [UCI_MIN_PROBE_COUNT] = {.name = "min_probe_count", .type = BLOBMSG_TYPE_INT32}, + [UCI_BANDWIDTH_THRESHOLD] = {.name = "bandwidth_threshold", .type = BLOBMSG_TYPE_INT32}, + [UCI_USE_STATION_COUNT] = {.name = "use_station_count", .type = BLOBMSG_TYPE_INT32}, + [UCI_MAX_STATION_DIFF] = {.name = "max_station_diff", .type = BLOBMSG_TYPE_INT32}, + [UCI_EVAL_PROBE_REQ] = {.name = "eval_probe_req", .type = BLOBMSG_TYPE_INT32}, + [UCI_EVAL_AUTH_REQ] = {.name = "eval_auth_req", .type = BLOBMSG_TYPE_INT32}, + [UCI_EVAL_ASSOC_REQ] = {.name = "eval_assoc_req", .type = BLOBMSG_TYPE_INT32}, + [UCI_KICKING] = {.name = "kicking", .type = BLOBMSG_TYPE_INT32}, + [UCI_DENY_AUTH_REASON] = {.name = "deny_auth_reason", .type = BLOBMSG_TYPE_INT32}, + [UCI_DENY_ASSOC_REASON] = {.name = "deny_assoc_reason", .type = BLOBMSG_TYPE_INT32}, + [UCI_USE_DRIVER_RECOG] = {.name = "use_driver_recog", .type = BLOBMSG_TYPE_INT32}, + [UCI_MIN_NUMBER_TO_KICK] = {.name = "min_number_to_kick", .type = BLOBMSG_TYPE_INT32}, + [UCI_CHAN_UTIL_AVG_PERIOD] = {.name = "chan_util_avg_period", .type = BLOBMSG_TYPE_INT32}, + [UCI_SET_HOSTAPD_NR] = {.name = "set_hostapd_nr", .type = BLOBMSG_TYPE_INT32}, + [UCI_OP_CLASS] = {.name = "op_class", .type = BLOBMSG_TYPE_INT32}, + [UCI_DURATION] = {.name = "duration", .type = BLOBMSG_TYPE_INT32}, + [UCI_MODE] = {.name = "mode", .type = BLOBMSG_TYPE_INT32}, + [UCI_SCAN_CHANNEL] = {.name = "mode", .type = BLOBMSG_TYPE_INT32}, +}; + +static const struct blobmsg_policy uci_times_policy[__UCI_TIMES_MAX] = { + [UCI_UPDATE_CLIENT] = {.name = "update_client", .type = BLOBMSG_TYPE_INT32}, + [UCI_DENIED_REQ_THRESHOLD] = {.name = "denied_req_threshold", .type = BLOBMSG_TYPE_INT32}, + [UCI_REMOVE_CLIENT] = {.name = "remove_client", .type = BLOBMSG_TYPE_INT32}, + [UCI_REMOVE_PROBE] = {.name = "remove_probe", .type = BLOBMSG_TYPE_INT32}, + [UCI_REMOVE_AP] = {.name = "remove_ap", .type = BLOBMSG_TYPE_INT32}, + [UCI_UPDATE_HOSTAPD] = {.name = "update_hostapd", .type = BLOBMSG_TYPE_INT32}, + [UCI_UPDATE_TCP_CON] = {.name = "update_tcp_con", .type = BLOBMSG_TYPE_INT32}, + [UCI_UPDATE_CHAN_UTIL] = {.name = "update_chan_util", .type = BLOBMSG_TYPE_INT32}, + [UCI_UPDATE_BEACON_REPORTS] = {.name = "update_beacon_reports", .type = BLOBMSG_TYPE_INT32}, +}; + +static int handle_uci_config(struct blob_attr* msg) { + + struct blob_attr* tb[__UCI_TABLE_MAX]; + blobmsg_parse(uci_table_policy, __UCI_TABLE_MAX, tb, blob_data(msg), blob_len(msg)); + + struct blob_attr* tb_metric[__UCI_METIC_MAX]; + blobmsg_parse(uci_metric_policy, __UCI_METIC_MAX, tb_metric, blobmsg_data(tb[UCI_TABLE_METRIC]), blobmsg_len(tb[UCI_TABLE_METRIC])); + + char cmd_buffer[1024]; + sprintf(cmd_buffer, "dawn.@metric[0].ht_support=%d", blobmsg_get_u32(tb_metric[UCI_HT_SUPPORT])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].vht_support=%d", blobmsg_get_u32(tb_metric[UCI_VHT_SUPPORT])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].no_ht_support=%d", blobmsg_get_u32(tb_metric[UCI_NO_HT_SUPPORT])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].no_vht_support=%d", blobmsg_get_u32(tb_metric[UCI_NO_VHT_SUPPORT])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].rssi=%d", blobmsg_get_u32(tb_metric[UCI_RSSI])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].low_rssi=%d", blobmsg_get_u32(tb_metric[UCI_LOW_RSSI])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].freq=%d", blobmsg_get_u32(tb_metric[UCI_FREQ])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].chan_util=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].rssi_val=%d", blobmsg_get_u32(tb_metric[UCI_RSSI_VAL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].low_rssi_val=%d", blobmsg_get_u32(tb_metric[UCI_LOW_RSSI_VAL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].chan_util_val=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL_VAL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].max_chan_util=%d", blobmsg_get_u32(tb_metric[UCI_MAX_CHAN_UTIL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].max_chan_util_val=%d", blobmsg_get_u32(tb_metric[UCI_MAX_CHAN_UTIL_VAL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].min_probe_count=%d", blobmsg_get_u32(tb_metric[UCI_MIN_PROBE_COUNT])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].bandwidth_threshold=%d", blobmsg_get_u32(tb_metric[UCI_BANDWIDTH_THRESHOLD])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].use_station_count=%d", blobmsg_get_u32(tb_metric[UCI_USE_STATION_COUNT])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].max_station_diff=%d", blobmsg_get_u32(tb_metric[UCI_MAX_STATION_DIFF])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].eval_probe_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_PROBE_REQ])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].eval_auth_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_AUTH_REQ])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].evalcd_assoc_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_ASSOC_REQ])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].kicking=%d", blobmsg_get_u32(tb_metric[UCI_KICKING])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].deny_auth_reason=%d", blobmsg_get_u32(tb_metric[UCI_DENY_AUTH_REASON])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].deny_assoc_reason=%d", blobmsg_get_u32(tb_metric[UCI_DENY_ASSOC_REASON])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].use_driver_recog=%d", blobmsg_get_u32(tb_metric[UCI_USE_DRIVER_RECOG])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].min_number_to_kick=%d", blobmsg_get_u32(tb_metric[UCI_MIN_NUMBER_TO_KICK])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].chan_util_avg_period=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL_AVG_PERIOD])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].set_hostapd_nr=%d", blobmsg_get_u32(tb_metric[UCI_SET_HOSTAPD_NR])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].op_class=%d", blobmsg_get_u32(tb_metric[UCI_OP_CLASS])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].duration=%d", blobmsg_get_u32(tb_metric[UCI_DURATION])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].mode=%d", blobmsg_get_u32(tb_metric[UCI_MODE])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@metric[0].scan_channel=%d", blobmsg_get_u32(tb_metric[UCI_SCAN_CHANNEL])); + uci_set_network(cmd_buffer); + + struct blob_attr* tb_times[__UCI_TIMES_MAX]; + blobmsg_parse(uci_times_policy, __UCI_TIMES_MAX, tb_times, blobmsg_data(tb[UCI_TABLE_TIMES]), blobmsg_len(tb[UCI_TABLE_TIMES])); + + sprintf(cmd_buffer, "dawn.@times[0].update_client=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_CLIENT])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@times[0].denied_req_threshold=%d", blobmsg_get_u32(tb_times[UCI_DENIED_REQ_THRESHOLD])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@times[0].remove_client=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_CLIENT])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@times[0].remove_probe=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_PROBE])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@times[0].remove_ap=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_AP])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@times[0].update_hostapd=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_HOSTAPD])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@times[0].update_tcp_con=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_TCP_CON])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@times[0].update_chan_util=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_CHAN_UTIL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.@times[0].update_beacon_reports=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_BEACON_REPORTS])); + uci_set_network(cmd_buffer); + + uci_reset(); + dawn_metric = uci_get_dawn_metric(); + timeout_config = uci_get_time_config(); + + return 0; +} + + + diff --git a/src/utils/ubus.c b/src/utils/ubus.c index a887cc5..2d3cb30 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -1,39 +1,24 @@ -#include - - -#include #include -#include -#include #include -#include -#include -#ifndef ETH_ALEN -#define ETH_ALEN 6 -#endif +#include "networksocket.h" +#include "tcpsocket.h" +#include "dawn_uci.h" +#include "dawn_iwinfo.h" +#include "datastorage.h" +#include "ubus.h" +#include "msghandler.h" + #define REQ_TYPE_PROBE 0 #define REQ_TYPE_AUTH 1 #define REQ_TYPE_ASSOC 2 -#include "networksocket.h" -#include "utils.h" -#include "dawn_uci.h" -#include "dawn_iwinfo.h" -#include "tcpsocket.h" -#include "ieee80211_utils.h" - -#include "datastorage.h" -#include "uface.h" -#include "ubus.h" static struct ubus_context *ctx = NULL; static struct blob_buf b; static struct blob_buf b_send_network; -static struct blob_buf network_buf; -static struct blob_buf data_buf; static struct blob_buf b_probe; static struct blob_buf b_domain; static struct blob_buf b_notify; @@ -65,6 +50,31 @@ struct uloop_timeout channel_utilization_timer = { .cb = update_channel_utilization }; +void remove_ap_array_cb(struct uloop_timeout* t); + +void denied_req_array_cb(struct uloop_timeout* t); + +void remove_client_array_cb(struct uloop_timeout* t); + +void remove_probe_array_cb(struct uloop_timeout* t); + +struct uloop_timeout probe_timeout = { + .cb = remove_probe_array_cb +}; + +struct uloop_timeout client_timeout = { + .cb = remove_client_array_cb +}; + +struct uloop_timeout ap_timeout = { + .cb = remove_ap_array_cb +}; + +struct uloop_timeout denied_req_timeout = { + .cb = denied_req_array_cb +}; + +// TODO: Never scheduled? struct uloop_timeout usock_timer = { .cb = run_server_update }; @@ -91,7 +101,7 @@ struct hostapd_sock_entry { uint64_t last_channel_time_busy; int chan_util_samples_sum; int chan_util_num_sample_periods; - int chan_util_average; + int chan_util_average; //TODO: Never evaluated? // add neighbor report string /* @@ -107,28 +117,6 @@ struct hostapd_sock_entry { struct hostapd_sock_entry* hostapd_sock_arr[MAX_HOSTAPD_SOCKETS]; int hostapd_sock_last = -1; -enum { - NETWORK_METHOD, - NETWORK_DATA, - __NETWORK_MAX, -}; - -static const struct blobmsg_policy network_policy[__NETWORK_MAX] = { - [NETWORK_METHOD] = {.name = "method", .type = BLOBMSG_TYPE_STRING}, - [NETWORK_DATA] = {.name = "data", .type = BLOBMSG_TYPE_STRING}, -}; - -enum { - HOSTAPD_NOTIFY_BSSID_ADDR, - HOSTAPD_NOTIFY_CLIENT_ADDR, - __HOSTAPD_NOTIFY_MAX, -}; - -static const struct blobmsg_policy hostapd_notify_policy[__HOSTAPD_NOTIFY_MAX] = { - [HOSTAPD_NOTIFY_BSSID_ADDR] = {.name = "bssid", .type = BLOBMSG_TYPE_STRING}, - [HOSTAPD_NOTIFY_CLIENT_ADDR] = {.name = "address", .type = BLOBMSG_TYPE_STRING}, -}; - enum { AUTH_BSSID_ADDR, AUTH_CLIENT_ADDR, @@ -146,31 +134,6 @@ static const struct blobmsg_policy auth_policy[__AUTH_MAX] = { [AUTH_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, }; -enum { - PROB_BSSID_ADDR, - PROB_CLIENT_ADDR, - PROB_TARGET_ADDR, - PROB_SIGNAL, - PROB_FREQ, - PROB_HT_CAPABILITIES, - PROB_VHT_CAPABILITIES, - PROB_RCPI, - PROB_RSNI, - __PROB_MAX, -}; - -static const struct blobmsg_policy prob_policy[__PROB_MAX] = { - [PROB_BSSID_ADDR] = {.name = "bssid", .type = BLOBMSG_TYPE_STRING}, - [PROB_CLIENT_ADDR] = {.name = "address", .type = BLOBMSG_TYPE_STRING}, - [PROB_TARGET_ADDR] = {.name = "target", .type = BLOBMSG_TYPE_STRING}, - [PROB_SIGNAL] = {.name = "signal", .type = BLOBMSG_TYPE_INT32}, - [PROB_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, - [PROB_HT_CAPABILITIES] = {.name = "ht_capabilities", .type = BLOBMSG_TYPE_TABLE}, - [PROB_VHT_CAPABILITIES] = {.name = "vht_capabilities", .type = BLOBMSG_TYPE_TABLE}, - [PROB_RCPI] = {.name = "rcpi", .type = BLOBMSG_TYPE_INT32}, - [PROB_RSNI] = {.name = "rsni", .type = BLOBMSG_TYPE_INT32}, -}; - enum { BEACON_REP_ADDR, BEACON_REP_OP_CLASS, @@ -200,74 +163,6 @@ static const struct blobmsg_policy beacon_rep_policy[__BEACON_REP_MAX] = { [BEACON_REP_PARENT_TSF] = {.name = "parent-tsf", .type = BLOBMSG_TYPE_INT16}, }; -enum { - CLIENT_TABLE, - CLIENT_TABLE_BSSID, - CLIENT_TABLE_SSID, - CLIENT_TABLE_FREQ, - CLIENT_TABLE_HT, - CLIENT_TABLE_VHT, - CLIENT_TABLE_CHAN_UTIL, - CLIENT_TABLE_NUM_STA, - CLIENT_TABLE_COL_DOMAIN, - CLIENT_TABLE_BANDWIDTH, - CLIENT_TABLE_WEIGHT, - CLIENT_TABLE_NEIGHBOR, - CLIENT_TABLE_IFACE, - CLIENT_TABLE_HOSTNAME, - __CLIENT_TABLE_MAX, -}; - -static const struct blobmsg_policy client_table_policy[__CLIENT_TABLE_MAX] = { - [CLIENT_TABLE] = {.name = "clients", .type = BLOBMSG_TYPE_TABLE}, - [CLIENT_TABLE_BSSID] = {.name = "bssid", .type = BLOBMSG_TYPE_STRING}, - [CLIENT_TABLE_SSID] = {.name = "ssid", .type = BLOBMSG_TYPE_STRING}, - [CLIENT_TABLE_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, - [CLIENT_TABLE_HT] = {.name = "ht_supported", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_TABLE_VHT] = {.name = "vht_supported", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_TABLE_CHAN_UTIL] = {.name = "channel_utilization", .type = BLOBMSG_TYPE_INT32}, - [CLIENT_TABLE_NUM_STA] = {.name = "num_sta", .type = BLOBMSG_TYPE_INT32}, - [CLIENT_TABLE_COL_DOMAIN] = {.name = "collision_domain", .type = BLOBMSG_TYPE_INT32}, - [CLIENT_TABLE_BANDWIDTH] = {.name = "bandwidth", .type = BLOBMSG_TYPE_INT32}, - [CLIENT_TABLE_WEIGHT] = {.name = "ap_weight", .type = BLOBMSG_TYPE_INT32}, - [CLIENT_TABLE_NEIGHBOR] = {.name = "neighbor_report", .type = BLOBMSG_TYPE_STRING}, - [CLIENT_TABLE_IFACE] = {.name = "iface", .type = BLOBMSG_TYPE_STRING}, - [CLIENT_TABLE_HOSTNAME] = {.name = "hostname", .type = BLOBMSG_TYPE_STRING}, -}; - -enum { - CLIENT_SIGNATURE, - CLIENT_AUTH, - CLIENT_ASSOC, - CLIENT_AUTHORIZED, - CLIENT_PREAUTH, - CLIENT_WDS, - CLIENT_WMM, - CLIENT_HT, - CLIENT_VHT, - CLIENT_WPS, - CLIENT_MFP, - CLIENT_AID, - CLIENT_RRM, - __CLIENT_MAX, -}; - -static const struct blobmsg_policy client_policy[__CLIENT_MAX] = { - [CLIENT_SIGNATURE] = {.name = "signature", .type = BLOBMSG_TYPE_STRING}, - [CLIENT_AUTH] = {.name = "auth", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_ASSOC] = {.name = "assoc", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_AUTHORIZED] = {.name = "authorized", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_PREAUTH] = {.name = "preauth", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_WDS] = {.name = "wds", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_WMM] = {.name = "wmm", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_HT] = {.name = "ht", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_VHT] = {.name = "vht", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_WPS] = {.name = "wps", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_MFP] = {.name = "mfp", .type = BLOBMSG_TYPE_INT8}, - [CLIENT_AID] = {.name = "aid", .type = BLOBMSG_TYPE_INT32}, - [CLIENT_RRM] = {.name = "rrm", .type = BLOBMSG_TYPE_ARRAY}, -}; - enum { DAWN_UMDNS_TABLE, __DAWN_UMDNS_TABLE_MAX, @@ -321,15 +216,11 @@ static int get_network(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg); -static int handle_set_probe(struct blob_attr *msg); - -static int parse_add_mac_to_file(struct blob_attr *msg); - static void ubus_add_oject(); static void respond_to_notify(uint32_t id); -int handle_uci_config(struct blob_attr *msg); +//static int handle_uci_config(struct blob_attr *msg); void subscribe_to_new_interfaces(const char *hostapd_sock_path); @@ -386,20 +277,6 @@ static int decide_function(probe_entry *prob_req, int req_type) { return 1; } -int parse_to_hostapd_notify(struct blob_attr *msg, hostapd_notify_entry *notify_req) { - struct blob_attr *tb[__HOSTAPD_NOTIFY_MAX]; - - blobmsg_parse(hostapd_notify_policy, __HOSTAPD_NOTIFY_MAX, tb, blob_data(msg), blob_len(msg)); - - if (hwaddr_aton(blobmsg_data(tb[HOSTAPD_NOTIFY_BSSID_ADDR]), notify_req->bssid_addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (hwaddr_aton(blobmsg_data(tb[HOSTAPD_NOTIFY_CLIENT_ADDR]), notify_req->client_addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - return 0; -} - int parse_to_auth_req(struct blob_attr *msg, auth_entry *auth_req) { struct blob_attr *tb[__AUTH_MAX]; @@ -414,11 +291,11 @@ int parse_to_auth_req(struct blob_attr *msg, auth_entry *auth_req) { if (hwaddr_aton(blobmsg_data(tb[AUTH_TARGET_ADDR]), auth_req->target_addr)) return UBUS_STATUS_INVALID_ARGUMENT; - if (tb[PROB_SIGNAL]) { + if (tb[AUTH_SIGNAL]) { auth_req->signal = blobmsg_get_u32(tb[AUTH_SIGNAL]); } - if (tb[PROB_FREQ]) { + if (tb[AUTH_FREQ]) { auth_req->freq = blobmsg_get_u32(tb[AUTH_FREQ]); } @@ -429,57 +306,6 @@ int parse_to_assoc_req(struct blob_attr *msg, assoc_entry *assoc_req) { return (parse_to_auth_req(msg, assoc_req)); } -int parse_to_probe_req(struct blob_attr *msg, probe_entry *prob_req) { - struct blob_attr *tb[__PROB_MAX]; - - blobmsg_parse(prob_policy, __PROB_MAX, tb, blob_data(msg), blob_len(msg)); - - if (hwaddr_aton(blobmsg_data(tb[PROB_BSSID_ADDR]), prob_req->bssid_addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (hwaddr_aton(blobmsg_data(tb[PROB_CLIENT_ADDR]), prob_req->client_addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (hwaddr_aton(blobmsg_data(tb[PROB_TARGET_ADDR]), prob_req->target_addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[PROB_SIGNAL]) { - prob_req->signal = blobmsg_get_u32(tb[PROB_SIGNAL]); - } - - if (tb[PROB_FREQ]) { - prob_req->freq = blobmsg_get_u32(tb[PROB_FREQ]); - } - - if (tb[PROB_RCPI]) { - prob_req->rcpi = blobmsg_get_u32(tb[PROB_RCPI]); - } else { - prob_req->rcpi = -1; - } - - if (tb[PROB_RSNI]) { - prob_req->rsni = blobmsg_get_u32(tb[PROB_RSNI]); - } else { - prob_req->rsni = -1; - } - - if (tb[PROB_HT_CAPABILITIES]) { - prob_req->ht_capabilities = true; - } else - { - prob_req->ht_capabilities = false; - } - - if (tb[PROB_VHT_CAPABILITIES]) { - prob_req->vht_capabilities = true; - } else - { - prob_req->vht_capabilities = false; - } - - return 0; -} - int parse_to_beacon_rep(struct blob_attr *msg, probe_entry *beacon_rep) { struct blob_attr *tb[__BEACON_REP_MAX]; @@ -522,7 +348,7 @@ int parse_to_beacon_rep(struct blob_attr *msg, probe_entry *beacon_rep) { { printf("Beacon: No Probe Entry Existing!\n"); beacon_rep->counter = dawn_metric.min_probe_count; - hwaddr_aton(blobmsg_data(tb[PROB_BSSID_ADDR]), beacon_rep->target_addr); + hwaddr_aton(blobmsg_data(tb[BEACON_REP_ADDR]), beacon_rep->target_addr); // TODO: Should this be ->bssid_addr? beacon_rep->signal = 0; beacon_rep->freq = ap_entry_rep.freq; beacon_rep->rcpi = rcpi; @@ -531,13 +357,14 @@ int parse_to_beacon_rep(struct blob_attr *msg, probe_entry *beacon_rep) { beacon_rep->ht_capabilities = false; // that is very problematic!!! beacon_rep->vht_capabilities = false; // that is very problematic!!! printf("Inserting to array!\n"); + beacon_rep->time = time(0); insert_to_array(*beacon_rep, false, false, true); ubus_send_probe_via_network(*beacon_rep); } return 0; } -static int handle_auth_req(struct blob_attr *msg) { +int handle_auth_req(struct blob_attr* msg) { print_probe_array(); auth_entry auth_req; @@ -560,6 +387,7 @@ static int handle_auth_req(struct blob_attr *msg) { printf("Deny authentication!\n"); if (dawn_metric.use_driver_recog) { + auth_req.time = time(0); insert_to_denied_req_array(auth_req, 1); } return dawn_metric.deny_auth_reason; @@ -568,6 +396,7 @@ static int handle_auth_req(struct blob_attr *msg) { if (!decide_function(&tmp, REQ_TYPE_AUTH)) { printf("Deny authentication\n"); if (dawn_metric.use_driver_recog) { + auth_req.time = time(0); insert_to_denied_req_array(auth_req, 1); } return dawn_metric.deny_auth_reason; @@ -599,6 +428,7 @@ static int handle_assoc_req(struct blob_attr *msg) { if (!(mac_is_equal(tmp.bssid_addr, auth_req.bssid_addr) && mac_is_equal(tmp.client_addr, auth_req.client_addr))) { printf("Deny associtation!\n"); if (dawn_metric.use_driver_recog) { + auth_req.time = time(0); insert_to_denied_req_array(auth_req, 1); } return dawn_metric.deny_assoc_reason; @@ -607,6 +437,7 @@ static int handle_assoc_req(struct blob_attr *msg) { if (!decide_function(&tmp, REQ_TYPE_ASSOC)) { printf("Deny association\n"); if (dawn_metric.use_driver_recog) { + auth_req.time = time(0); insert_to_denied_req_array(auth_req, 1); } return dawn_metric.deny_assoc_reason; @@ -621,7 +452,8 @@ static int handle_probe_req(struct blob_attr *msg) { probe_entry tmp_prob_req; if (parse_to_probe_req(msg, &prob_req) == 0) { - tmp_prob_req = insert_to_array(prob_req, 1, true, false); + prob_req.time = time(0); + tmp_prob_req = insert_to_array(prob_req, 1, true, false); // TODO: Chnage 1 to true? ubus_send_probe_via_network(tmp_prob_req); //send_blob_attr_via_network(msg, "probe"); } @@ -644,111 +476,6 @@ static int handle_beacon_rep(struct blob_attr *msg) { return 0; } -static int handle_deauth_req(struct blob_attr *msg) { - - hostapd_notify_entry notify_req; - parse_to_hostapd_notify(msg, ¬ify_req); - - client client_entry; - memcpy(client_entry.bssid_addr, notify_req.bssid_addr, sizeof(uint8_t) * ETH_ALEN); - memcpy(client_entry.client_addr, notify_req.client_addr, sizeof(uint8_t) * ETH_ALEN); - - pthread_mutex_lock(&client_array_mutex); - client_array_delete(client_entry); - pthread_mutex_unlock(&client_array_mutex); - - printf("[WC] Deauth: %s\n", "deauth"); - - return 0; -} - -static int handle_set_probe(struct blob_attr *msg) { - - hostapd_notify_entry notify_req; - parse_to_hostapd_notify(msg, ¬ify_req); - - client client_entry; - memcpy(client_entry.bssid_addr, notify_req.bssid_addr, sizeof(uint8_t) * ETH_ALEN); - memcpy(client_entry.client_addr, notify_req.client_addr, sizeof(uint8_t) * ETH_ALEN); - - probe_array_set_all_probe_count(client_entry.client_addr, dawn_metric.min_probe_count); - - return 0; -} - -int handle_network_msg(char *msg) { - struct blob_attr *tb[__NETWORK_MAX]; - char *method; - char *data; - - blob_buf_init(&network_buf, 0); - blobmsg_add_json_from_string(&network_buf, msg); - - blobmsg_parse(network_policy, __NETWORK_MAX, tb, blob_data(network_buf.head), blob_len(network_buf.head)); - - if (!tb[NETWORK_METHOD] || !tb[NETWORK_DATA]) { - return -1; - } - - method = blobmsg_data(tb[NETWORK_METHOD]); - data = blobmsg_data(tb[NETWORK_DATA]); - - printf("Network Method new: %s : %s\n", method, msg); - - blob_buf_init(&data_buf, 0); - blobmsg_add_json_from_string(&data_buf, data); - - if (!data_buf.head) { - return -1; - } - - if (blob_len(data_buf.head) <= 0) { - return -1; - } - - if (strlen(method) < 2) { - return -1; - } - - // add inactive death... - -// TODO: strncmp() look wrong - should all tests be for n = 5 characters? Shorthand checks? - if (strncmp(method, "probe", 5) == 0) { - probe_entry entry; - if (parse_to_probe_req(data_buf.head, &entry) == 0) { - insert_to_array(entry, 0, false, false); // use 802.11k values - } - } else if (strncmp(method, "clients", 5) == 0) { - parse_to_clients(data_buf.head, 0, 0); - } else if (strncmp(method, "deauth", 5) == 0) { - printf("METHOD DEAUTH\n"); - handle_deauth_req(data_buf.head); - } else if (strncmp(method, "setprobe", 5) == 0) { - printf("HANDLING SET PROBE!\n"); - handle_set_probe(data_buf.head); - } else if (strncmp(method, "addmac", 5) == 0) { - parse_add_mac_to_file(data_buf.head); - } else if (strncmp(method, "macfile", 5) == 0) { - parse_add_mac_to_file(data_buf.head); - } else if (strncmp(method, "uci", 2) == 0) { - printf("HANDLING UCI!\n"); - handle_uci_config(data_buf.head); - } else if (strncmp(method, "beacon-report", 12) == 0) { - // TODO: Check beacon report stuff - - //printf("HANDLING BEACON REPORT NETWORK!\n"); - //printf("The Method for beacon-report is: %s\n", method); - // ignore beacon reports send via network!, use probe functions for it - //probe_entry entry; // for now just stay at probe entry stuff... - //parse_to_beacon_rep(data_buf.head, &entry, true); - } else - { - printf("No method fonud for: %s\n", method); - } - - return 0; -} - int send_blob_attr_via_network(struct blob_attr *msg, char *method) { @@ -836,19 +563,19 @@ int dawn_init_ubus(const char *ubus_socket, const char *hostapd_dir) { // set dawn metric dawn_metric = uci_get_dawn_metric(); - uloop_timeout_add(&hostapd_timer); + uloop_timeout_add(&hostapd_timer); // callback = update_hostapd_sockets - // remove probe + // set up callbacks to remove aged data uloop_add_data_cbs(); // get clients - uloop_timeout_add(&client_timer); + uloop_timeout_add(&client_timer); // callback = update_clients - uloop_timeout_add(&channel_utilization_timer); + uloop_timeout_add(&channel_utilization_timer); // callback = update_channel_utilization // request beacon reports if(timeout_config.update_beacon_reports) // allow setting timeout to 0 - uloop_timeout_add(&beacon_reports_timer); + uloop_timeout_add(&beacon_reports_timer); // callback = update_beacon_reports ubus_add_oject(); @@ -870,223 +597,6 @@ int dawn_init_ubus(const char *ubus_socket, const char *hostapd_dir) { return 0; } -static uint8_t dump_rrm_data(void *data, int len, int type) //modify from examples/blobmsg-example.c in libubox -{ - uint32_t ret = 0; - switch(type) { - case BLOBMSG_TYPE_INT32: - ret = *(uint32_t *)data; - break; - default: - fprintf(stderr, "wrong type of rrm array\n"); - } - return (uint8_t)ret; -} - -static uint8_t -dump_rrm_table(struct blob_attr *head, int len) //modify from examples/blobmsg-example.c in libubox -{ - struct blob_attr *attr; - uint8_t ret = 0; - - __blob_for_each_attr(attr, head, len) { - ret = dump_rrm_data(blobmsg_data(attr), blobmsg_data_len(attr), blob_id(attr)); - return ret;// get the first rrm byte - } - return ret; -} - -// TOOD: Refactor this! -static void -dump_client(struct blob_attr **tb, uint8_t client_addr[], const char *bssid_addr, uint32_t freq, uint8_t ht_supported, - uint8_t vht_supported) { - client client_entry; - - hwaddr_aton(bssid_addr, client_entry.bssid_addr); - memcpy(client_entry.client_addr, client_addr, ETH_ALEN * sizeof(uint8_t)); - client_entry.freq = freq; - client_entry.ht_supported = ht_supported; - client_entry.vht_supported = vht_supported; - - if (tb[CLIENT_AUTH]) { - client_entry.auth = blobmsg_get_u8(tb[CLIENT_AUTH]); - } - if (tb[CLIENT_ASSOC]) { - client_entry.assoc = blobmsg_get_u8(tb[CLIENT_ASSOC]); - } - if (tb[CLIENT_AUTHORIZED]) { - client_entry.authorized = blobmsg_get_u8(tb[CLIENT_AUTHORIZED]); - } - if (tb[CLIENT_PREAUTH]) { - client_entry.preauth = blobmsg_get_u8(tb[CLIENT_PREAUTH]); - } - if (tb[CLIENT_WDS]) { - client_entry.wds = blobmsg_get_u8(tb[CLIENT_WDS]); - } - if (tb[CLIENT_WMM]) { - client_entry.wmm = blobmsg_get_u8(tb[CLIENT_WMM]); - } - if (tb[CLIENT_HT]) { - client_entry.ht = blobmsg_get_u8(tb[CLIENT_HT]); - } - if (tb[CLIENT_VHT]) { - client_entry.vht = blobmsg_get_u8(tb[CLIENT_VHT]); - } - if (tb[CLIENT_WPS]) { - client_entry.wps = blobmsg_get_u8(tb[CLIENT_WPS]); - } - if (tb[CLIENT_MFP]) { - client_entry.mfp = blobmsg_get_u8(tb[CLIENT_MFP]); - } - if (tb[CLIENT_AID]) { - client_entry.aid = blobmsg_get_u32(tb[CLIENT_AID]); - } - /* RRM Caps */ - if (tb[CLIENT_RRM]) { - client_entry.rrm_enabled_capa = dump_rrm_table(blobmsg_data(tb[CLIENT_RRM]), - blobmsg_data_len(tb[CLIENT_RRM]));// get the first byte from rrm array - //ap_entry.ap_weight = blobmsg_get_u32(tb[CLIENT_TABLE_RRM]); - } else { - client_entry.rrm_enabled_capa = 0; - //ap_entry.ap_weight = 0; - } - - // copy signature - if (tb[CLIENT_SIGNATURE]) { - memcpy(client_entry.signature, blobmsg_data(tb[CLIENT_SIGNATURE]), SIGNATURE_LEN * sizeof(char)); - } else - { - memset(client_entry.signature, 0, 1024); - } - - insert_client_to_array(client_entry); -} - -static int -dump_client_table(struct blob_attr *head, int len, const char *bssid_addr, uint32_t freq, uint8_t ht_supported, - uint8_t vht_supported) { - struct blob_attr *attr; - struct blobmsg_hdr *hdr; - int station_count = 0; - - __blob_for_each_attr(attr, head, len) - { - hdr = blob_data(attr); - - struct blob_attr *tb[__CLIENT_MAX]; - blobmsg_parse(client_policy, __CLIENT_MAX, tb, blobmsg_data(attr), blobmsg_len(attr)); - //char* str = blobmsg_format_json_indent(attr, true, -1); - - int tmp_int_mac[ETH_ALEN]; - uint8_t tmp_mac[ETH_ALEN]; - sscanf((char *) hdr->name, MACSTR, STR2MAC(tmp_int_mac)); - for (int i = 0; i < ETH_ALEN; ++i) - tmp_mac[i] = (uint8_t) tmp_int_mac[i]; - - dump_client(tb, tmp_mac, bssid_addr, freq, ht_supported, vht_supported); - station_count++; - } - return station_count; -} - -int parse_to_clients(struct blob_attr *msg, int do_kick, uint32_t id) { - struct blob_attr *tb[__CLIENT_TABLE_MAX]; - - if (!msg) { - return -1; - } - - if (!blob_data(msg)) { - return -1; - } - - if (blob_len(msg) <= 0) { - return -1; - } - - blobmsg_parse(client_table_policy, __CLIENT_TABLE_MAX, tb, blob_data(msg), blob_len(msg)); - - if (tb[CLIENT_TABLE] && tb[CLIENT_TABLE_BSSID] && tb[CLIENT_TABLE_FREQ]) { - int num_stations = 0; - num_stations = dump_client_table(blobmsg_data(tb[CLIENT_TABLE]), blobmsg_data_len(tb[CLIENT_TABLE]), - blobmsg_data(tb[CLIENT_TABLE_BSSID]), blobmsg_get_u32(tb[CLIENT_TABLE_FREQ]), - blobmsg_get_u8(tb[CLIENT_TABLE_HT]), blobmsg_get_u8(tb[CLIENT_TABLE_VHT])); - ap ap_entry; - hwaddr_aton(blobmsg_data(tb[CLIENT_TABLE_BSSID]), ap_entry.bssid_addr); - ap_entry.freq = blobmsg_get_u32(tb[CLIENT_TABLE_FREQ]); - - if(tb[CLIENT_TABLE_HT]){ - ap_entry.ht_support = blobmsg_get_u8(tb[CLIENT_TABLE_HT]); - } else { - ap_entry.ht_support = false; - } - - if(tb[CLIENT_TABLE_VHT]){ - ap_entry.vht_support = blobmsg_get_u8(tb[CLIENT_TABLE_VHT]); - } else - { - ap_entry.vht_support = false; - } - - if(tb[CLIENT_TABLE_CHAN_UTIL]) { - ap_entry.channel_utilization = blobmsg_get_u32(tb[CLIENT_TABLE_CHAN_UTIL]); - } else // if this is not existing set to 0? - { - ap_entry.channel_utilization = 0; - } - - if(tb[CLIENT_TABLE_SSID]) { - strcpy((char *) ap_entry.ssid, blobmsg_get_string(tb[CLIENT_TABLE_SSID])); - } - - if (tb[CLIENT_TABLE_COL_DOMAIN]) { - ap_entry.collision_domain = blobmsg_get_u32(tb[CLIENT_TABLE_COL_DOMAIN]); - } else { - ap_entry.collision_domain = -1; - } - - if (tb[CLIENT_TABLE_BANDWIDTH]) { - ap_entry.bandwidth = blobmsg_get_u32(tb[CLIENT_TABLE_BANDWIDTH]); - } else { - ap_entry.bandwidth = -1; - } - - ap_entry.station_count = num_stations; - - if (tb[CLIENT_TABLE_WEIGHT]) { - ap_entry.ap_weight = blobmsg_get_u32(tb[CLIENT_TABLE_WEIGHT]); - } else { - ap_entry.ap_weight = 0; - } - - - if (tb[CLIENT_TABLE_NEIGHBOR]) { - strncpy(ap_entry.neighbor_report, blobmsg_get_string(tb[CLIENT_TABLE_NEIGHBOR]), NEIGHBOR_REPORT_LEN); - } else { - ap_entry.neighbor_report[0] = '\0'; - } - - if (tb[CLIENT_TABLE_IFACE]) { - strncpy(ap_entry.iface, blobmsg_get_string(tb[CLIENT_TABLE_IFACE]), MAX_INTERFACE_NAME); - } else { - ap_entry.iface[0] = '\0'; - } - - if (tb[CLIENT_TABLE_HOSTNAME]) { - strncpy(ap_entry.hostname, blobmsg_get_string(tb[CLIENT_TABLE_HOSTNAME]), HOST_NAME_MAX); - } else { - ap_entry.hostname[0] = '\0'; - } - - insert_to_ap_array(ap_entry); - - if (do_kick && dawn_metric.kicking) { - kick_clients(ap_entry.bssid_addr, id); - } - } - return 0; -} - static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_attr *msg) { struct hostapd_sock_entry *sub, *entry = NULL; @@ -1134,6 +644,7 @@ static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_ blobmsg_add_string(&b_domain, "hostname", entry->hostname); send_blob_attr_via_network(b_domain.head, "clients"); + // TODO: Have we just bit-packed data to send to something locally to unpack it again? Performance / scalability? parse_to_clients(b_domain.head, 1, req->peer); print_client_array(); @@ -1279,7 +790,7 @@ void update_tcp_connections(struct uloop_timeout *t) { void start_umdns_update() { // update connections - uloop_timeout_add(&umdns_timer); + uloop_timeout_add(&umdns_timer); // callback = update_tcp_connections } void update_hostapd_sockets(struct uloop_timeout *t) { @@ -1340,7 +851,7 @@ void del_client_interface(uint32_t id, const uint8_t *client_addr, uint32_t reas } -void wnm_disassoc_imminent(uint32_t id, const uint8_t *client_addr, char* dest_ap, uint32_t duration) { +int wnm_disassoc_imminent(uint32_t id, const uint8_t *client_addr, char *dest_ap, uint32_t duration) { struct hostapd_sock_entry *sub; blob_buf_init(&b, 0); @@ -1350,7 +861,7 @@ void wnm_disassoc_imminent(uint32_t id, const uint8_t *client_addr, char* dest_a // ToDo: maybe exchange to a list of aps void* nbs = blobmsg_open_array(&b, "neighbors"); - if(dest_ap!=NULL) + if (dest_ap != NULL) { blobmsg_add_string(&b, NULL, dest_ap); printf("BSS TRANSITION TO %s\n", dest_ap); @@ -1364,6 +875,8 @@ void wnm_disassoc_imminent(uint32_t id, const uint8_t *client_addr, char* dest_a ubus_invoke(ctx, id, "wnm_disassoc_imminent", b.head, NULL, NULL, timeout * 1000); } } + + return 0; } static void ubus_umdns_cb(struct ubus_request *req, int type, struct blob_attr *msg) { @@ -1427,13 +940,13 @@ int ubus_send_probe_via_network(struct probe_entry_s probe_entry) { blobmsg_add_u32(&b_probe, "rcpi", probe_entry.rcpi); blobmsg_add_u32(&b_probe, "rsni", probe_entry.rsni); - if(probe_entry.ht_capabilities) + if (probe_entry.ht_capabilities) { void *ht_cap = blobmsg_open_table(&b, "ht_capabilities"); blobmsg_close_table(&b, ht_cap); } - if(probe_entry.vht_capabilities) { + if (probe_entry.vht_capabilities) { void *vht_cap = blobmsg_open_table(&b, "vht_capabilities"); blobmsg_close_table(&b, vht_cap); } @@ -1479,10 +992,10 @@ static struct ubus_object dawn_object = { .n_methods = ARRAY_SIZE(dawn_methods), }; -static int parse_add_mac_to_file(struct blob_attr *msg) { +int parse_add_mac_to_file(struct blob_attr *msg) { struct blob_attr *tb[__ADD_DEL_MAC_MAX]; struct blob_attr *attr; - + printf("Parsing MAC!\n"); blobmsg_parse(add_del_policy, __ADD_DEL_MAC_MAX, tb, blob_data(msg), blob_len(msg)); @@ -1500,8 +1013,8 @@ static int parse_add_mac_to_file(struct blob_attr *msg) { hwaddr_aton(blobmsg_data(attr), addr); if (insert_to_maclist(addr) == 0) { -// TODO: File can grow arbitarily large. Resource consumption risk. -// TODO: Consolidate use of file across source: shared resource for name, single point of access? + // TODO: File can grow arbitarily large. Resource consumption risk. + // TODO: Consolidate use of file across source: shared resource for name, single point of access? write_mac_to_file("/tmp/dawn_mac_list", addr); } } @@ -1539,7 +1052,7 @@ static int reload_config(struct ubus_context *ctx, struct ubus_object *obj, uci_get_dawn_sort_order(); if(timeout_config.update_beacon_reports) // allow setting timeout to 0 - uloop_timeout_add(&beacon_reports_timer); + uloop_timeout_add(&beacon_reports_timer); // callback = update_beacon_reports uci_send_via_network(); ret = ubus_send_reply(ctx, req, b.head); @@ -1602,7 +1115,7 @@ static void enable_rrm(uint32_t id) { blob_buf_init(&b, 0); blobmsg_add_u8(&b, "neighbor_report", 1); blobmsg_add_u8(&b, "beacon_report", 1); - blobmsg_add_u8(&b, "bss_transition", 1); + blobmsg_add_u8(&b, "bss_transition", 1); int timeout = 1; ret = ubus_invoke(ctx, id, "bss_mgmt_enable", b.head, NULL, NULL, timeout * 1000); @@ -1620,7 +1133,7 @@ static void hostapd_handle_remove(struct ubus_context *ctx, printf("ID is not the same!\n"); return; } - + hostapd_sock->subscribed = false; subscription_wait(&hostapd_sock->wait_handler); @@ -1649,7 +1162,7 @@ bool subscribe(struct hostapd_sock_entry *hostapd_entry) { hostapd_entry->subscribed = true; get_bssid(hostapd_entry->iface_name, hostapd_entry->bssid_addr); - get_ssid(hostapd_entry->iface_name, hostapd_entry->ssid); + get_ssid(hostapd_entry->iface_name, hostapd_entry->ssid, (SSID_MAX_LEN) * sizeof(char)); hostapd_entry->ht_support = (uint8_t) support_ht(hostapd_entry->iface_name); hostapd_entry->vht_support = (uint8_t) support_vht(hostapd_entry->iface_name); @@ -1673,7 +1186,7 @@ wait_cb(struct ubus_context *ctx, struct ubus_event_handler *ev_handler, struct blob_attr *attr; const char *path; struct hostapd_sock_entry *sub = container_of(ev_handler, - struct hostapd_sock_entry, wait_handler); + struct hostapd_sock_entry, wait_handler); if (strcmp(type, "ubus.object.add")) return; @@ -1813,250 +1326,6 @@ int uci_send_via_network() return 0; } -enum { - UCI_TABLE_METRIC, - UCI_TABLE_TIMES, - __UCI_TABLE_MAX -}; - -enum { - UCI_HT_SUPPORT, - UCI_VHT_SUPPORT, - UCI_NO_HT_SUPPORT, - UCI_NO_VHT_SUPPORT, - UCI_RSSI, - UCI_LOW_RSSI, - UCI_FREQ, - UCI_CHAN_UTIL, - UCI_MAX_CHAN_UTIL, - UCI_RSSI_VAL, - UCI_LOW_RSSI_VAL, - UCI_CHAN_UTIL_VAL, - UCI_MAX_CHAN_UTIL_VAL, - UCI_MIN_PROBE_COUNT, - UCI_BANDWIDTH_THRESHOLD, - UCI_USE_STATION_COUNT, - UCI_MAX_STATION_DIFF, - UCI_EVAL_PROBE_REQ, - UCI_EVAL_AUTH_REQ, - UCI_EVAL_ASSOC_REQ, - UCI_KICKING, - UCI_DENY_AUTH_REASON, - UCI_DENY_ASSOC_REASON, - UCI_USE_DRIVER_RECOG, - UCI_MIN_NUMBER_TO_KICK, - UCI_CHAN_UTIL_AVG_PERIOD, - UCI_SET_HOSTAPD_NR, - UCI_OP_CLASS, - UCI_DURATION, - UCI_MODE, - UCI_SCAN_CHANNEL, - __UCI_METIC_MAX -}; - -enum { - UCI_UPDATE_CLIENT, - UCI_DENIED_REQ_THRESHOLD, - UCI_REMOVE_CLIENT, - UCI_REMOVE_PROBE, - UCI_REMOVE_AP, - UCI_UPDATE_HOSTAPD, - UCI_UPDATE_TCP_CON, - UCI_UPDATE_CHAN_UTIL, - UCI_UPDATE_BEACON_REPORTS, - __UCI_TIMES_MAX, -}; - -static const struct blobmsg_policy uci_table_policy[__UCI_TABLE_MAX] = { - [UCI_TABLE_METRIC] = {.name = "metric", .type = BLOBMSG_TYPE_TABLE}, - [UCI_TABLE_TIMES] = {.name = "times", .type = BLOBMSG_TYPE_TABLE} -}; - -static const struct blobmsg_policy uci_metric_policy[__UCI_METIC_MAX] = { - [UCI_HT_SUPPORT] = {.name = "ht_support", .type = BLOBMSG_TYPE_INT32}, - [UCI_VHT_SUPPORT] = {.name = "vht_support", .type = BLOBMSG_TYPE_INT32}, - [UCI_NO_HT_SUPPORT] = {.name = "no_ht_support", .type = BLOBMSG_TYPE_INT32}, - [UCI_NO_VHT_SUPPORT] = {.name = "no_vht_support", .type = BLOBMSG_TYPE_INT32}, - [UCI_RSSI] = {.name = "rssi", .type = BLOBMSG_TYPE_INT32}, - [UCI_LOW_RSSI] = {.name = "low_rssi", .type = BLOBMSG_TYPE_INT32}, - [UCI_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, - [UCI_CHAN_UTIL] = {.name = "chan_util", .type = BLOBMSG_TYPE_INT32}, - [UCI_MAX_CHAN_UTIL] = {.name = "max_chan_util", .type = BLOBMSG_TYPE_INT32}, - [UCI_RSSI_VAL] = {.name = "rssi_val", .type = BLOBMSG_TYPE_INT32}, - [UCI_LOW_RSSI_VAL] = {.name = "low_rssi_val", .type = BLOBMSG_TYPE_INT32}, - [UCI_CHAN_UTIL_VAL] = {.name = "chan_util_val", .type = BLOBMSG_TYPE_INT32}, - [UCI_MAX_CHAN_UTIL_VAL] = {.name = "max_chan_util_val", .type = BLOBMSG_TYPE_INT32}, - [UCI_MIN_PROBE_COUNT] = {.name = "min_probe_count", .type = BLOBMSG_TYPE_INT32}, - [UCI_BANDWIDTH_THRESHOLD] = {.name = "bandwidth_threshold", .type = BLOBMSG_TYPE_INT32}, - [UCI_USE_STATION_COUNT] = {.name = "use_station_count", .type = BLOBMSG_TYPE_INT32}, - [UCI_MAX_STATION_DIFF] = {.name = "max_station_diff", .type = BLOBMSG_TYPE_INT32}, - [UCI_EVAL_PROBE_REQ] = {.name = "eval_probe_req", .type = BLOBMSG_TYPE_INT32}, - [UCI_EVAL_AUTH_REQ] = {.name = "eval_auth_req", .type = BLOBMSG_TYPE_INT32}, - [UCI_EVAL_ASSOC_REQ] = {.name = "eval_assoc_req", .type = BLOBMSG_TYPE_INT32}, - [UCI_KICKING] = {.name = "kicking", .type = BLOBMSG_TYPE_INT32}, - [UCI_DENY_AUTH_REASON] = {.name = "deny_auth_reason", .type = BLOBMSG_TYPE_INT32}, - [UCI_DENY_ASSOC_REASON] = {.name = "deny_assoc_reason", .type = BLOBMSG_TYPE_INT32}, - [UCI_USE_DRIVER_RECOG] = {.name = "use_driver_recog", .type = BLOBMSG_TYPE_INT32}, - [UCI_MIN_NUMBER_TO_KICK] = {.name = "min_number_to_kick", .type = BLOBMSG_TYPE_INT32}, - [UCI_CHAN_UTIL_AVG_PERIOD] = {.name = "chan_util_avg_period", .type = BLOBMSG_TYPE_INT32}, - [UCI_SET_HOSTAPD_NR] = {.name = "set_hostapd_nr", .type = BLOBMSG_TYPE_INT32}, - [UCI_OP_CLASS] = {.name = "op_class", .type = BLOBMSG_TYPE_INT32}, - [UCI_DURATION] = {.name = "duration", .type = BLOBMSG_TYPE_INT32}, - [UCI_MODE] = {.name = "mode", .type = BLOBMSG_TYPE_INT32}, - [UCI_SCAN_CHANNEL] = {.name = "mode", .type = BLOBMSG_TYPE_INT32}, -}; - -static const struct blobmsg_policy uci_times_policy[__UCI_TIMES_MAX] = { - [UCI_UPDATE_CLIENT] = {.name = "update_client", .type = BLOBMSG_TYPE_INT32}, - [UCI_DENIED_REQ_THRESHOLD] = {.name = "denied_req_threshold", .type = BLOBMSG_TYPE_INT32}, - [UCI_REMOVE_CLIENT] = {.name = "remove_client", .type = BLOBMSG_TYPE_INT32}, - [UCI_REMOVE_PROBE] = {.name = "remove_probe", .type = BLOBMSG_TYPE_INT32}, - [UCI_REMOVE_AP] = {.name = "remove_ap", .type = BLOBMSG_TYPE_INT32}, - [UCI_UPDATE_HOSTAPD] = {.name = "update_hostapd", .type = BLOBMSG_TYPE_INT32}, - [UCI_UPDATE_TCP_CON] = {.name = "update_tcp_con", .type = BLOBMSG_TYPE_INT32}, - [UCI_UPDATE_CHAN_UTIL] = {.name = "update_chan_util", .type = BLOBMSG_TYPE_INT32}, - [UCI_UPDATE_BEACON_REPORTS] = {.name = "update_beacon_reports", .type = BLOBMSG_TYPE_INT32}, -}; - -int handle_uci_config(struct blob_attr *msg) { - - struct blob_attr *tb[__UCI_TABLE_MAX]; - blobmsg_parse(uci_table_policy, __UCI_TABLE_MAX, tb, blob_data(msg), blob_len(msg)); - - struct blob_attr *tb_metric[__UCI_METIC_MAX]; - blobmsg_parse(uci_metric_policy, __UCI_METIC_MAX, tb_metric, blobmsg_data(tb[UCI_TABLE_METRIC]), blobmsg_len(tb[UCI_TABLE_METRIC])); - - char cmd_buffer[1024]; - sprintf(cmd_buffer, "dawn.@metric[0].ht_support=%d", blobmsg_get_u32(tb_metric[UCI_HT_SUPPORT])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].vht_support=%d", blobmsg_get_u32(tb_metric[UCI_VHT_SUPPORT])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].no_ht_support=%d", blobmsg_get_u32(tb_metric[UCI_NO_HT_SUPPORT])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].no_vht_support=%d", blobmsg_get_u32(tb_metric[UCI_NO_VHT_SUPPORT])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].rssi=%d", blobmsg_get_u32(tb_metric[UCI_RSSI])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].low_rssi=%d", blobmsg_get_u32(tb_metric[UCI_LOW_RSSI])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].freq=%d", blobmsg_get_u32(tb_metric[UCI_FREQ])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].chan_util=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].rssi_val=%d", blobmsg_get_u32(tb_metric[UCI_RSSI_VAL])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].low_rssi_val=%d", blobmsg_get_u32(tb_metric[UCI_LOW_RSSI_VAL])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].chan_util_val=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL_VAL])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].max_chan_util=%d", blobmsg_get_u32(tb_metric[UCI_MAX_CHAN_UTIL])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].max_chan_util_val=%d", blobmsg_get_u32(tb_metric[UCI_MAX_CHAN_UTIL_VAL])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].min_probe_count=%d", blobmsg_get_u32(tb_metric[UCI_MIN_PROBE_COUNT])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].bandwidth_threshold=%d", blobmsg_get_u32(tb_metric[UCI_BANDWIDTH_THRESHOLD])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].use_station_count=%d", blobmsg_get_u32(tb_metric[UCI_USE_STATION_COUNT])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].max_station_diff=%d", blobmsg_get_u32(tb_metric[UCI_MAX_STATION_DIFF])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].eval_probe_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_PROBE_REQ])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].eval_auth_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_AUTH_REQ])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].evalcd_assoc_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_ASSOC_REQ])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].kicking=%d", blobmsg_get_u32(tb_metric[UCI_KICKING])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].deny_auth_reason=%d", blobmsg_get_u32(tb_metric[UCI_DENY_AUTH_REASON])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].deny_assoc_reason=%d", blobmsg_get_u32(tb_metric[UCI_DENY_ASSOC_REASON])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].use_driver_recog=%d", blobmsg_get_u32(tb_metric[UCI_USE_DRIVER_RECOG])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].min_number_to_kick=%d", blobmsg_get_u32(tb_metric[UCI_MIN_NUMBER_TO_KICK])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].chan_util_avg_period=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL_AVG_PERIOD])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].set_hostapd_nr=%d", blobmsg_get_u32(tb_metric[UCI_SET_HOSTAPD_NR])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].op_class=%d", blobmsg_get_u32(tb_metric[UCI_OP_CLASS])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].duration=%d", blobmsg_get_u32(tb_metric[UCI_DURATION])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].mode=%d", blobmsg_get_u32(tb_metric[UCI_MODE])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@metric[0].scan_channel=%d", blobmsg_get_u32(tb_metric[UCI_SCAN_CHANNEL])); - uci_set_network(cmd_buffer); - - struct blob_attr *tb_times[__UCI_TIMES_MAX]; - blobmsg_parse(uci_times_policy, __UCI_TIMES_MAX, tb_times, blobmsg_data(tb[UCI_TABLE_TIMES]), blobmsg_len(tb[UCI_TABLE_TIMES])); - - sprintf(cmd_buffer, "dawn.@times[0].update_client=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_CLIENT])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@times[0].denied_req_threshold=%d", blobmsg_get_u32(tb_times[UCI_DENIED_REQ_THRESHOLD])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@times[0].remove_client=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_CLIENT])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@times[0].remove_probe=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_PROBE])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@times[0].remove_ap=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_AP])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@times[0].update_hostapd=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_HOSTAPD])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@times[0].update_tcp_con=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_TCP_CON])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@times[0].update_chan_util=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_CHAN_UTIL])); - uci_set_network(cmd_buffer); - - sprintf(cmd_buffer, "dawn.@times[0].update_beacon_reports=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_BEACON_REPORTS])); - uci_set_network(cmd_buffer); - - uci_reset(); - dawn_metric = uci_get_dawn_metric(); - timeout_config = uci_get_time_config(); - - return 0; -} - int build_hearing_map_sort_client(struct blob_buf *b) { print_probe_array(); pthread_mutex_lock(&probe_array_mutex); @@ -2184,7 +1453,7 @@ int build_network_overview(struct blob_buf *b) { char *nr; nr = blobmsg_alloc_string_buffer(b, "neighbor_report", NEIGHBOR_REPORT_LEN); - sprintf(nr, "%s", ap_array[m].neighbor_report); + sprintf(nr, "%s", ap_array[m].neighbor_report); // TODO: Why not strcpy() blobmsg_add_string_buffer(b); char *iface; @@ -2265,3 +1534,86 @@ int ap_get_nr(struct blob_buf *b_local, uint8_t own_bssid_addr[]) { return 0; } + +void uloop_add_data_cbs() { + uloop_timeout_add(&probe_timeout); // callback = remove_probe_array_cb + uloop_timeout_add(&client_timeout); // callback = remove_client_array_cb + uloop_timeout_add(&ap_timeout); // callback = remove_ap_array_cb + + if (dawn_metric.use_driver_recog) { + uloop_timeout_add(&denied_req_timeout); // callback = denied_req_array_cb + } +} + +// TODO: Move mutex handling to remove_??? function to make test harness simpler? +// Or not needed as test harness not threaded? +void remove_probe_array_cb(struct uloop_timeout* t) { + pthread_mutex_lock(&probe_array_mutex); + printf("[Thread] : Removing old probe entries!\n"); + remove_old_probe_entries(time(0), timeout_config.remove_probe); + printf("[Thread] : Removing old entries finished!\n"); + pthread_mutex_unlock(&probe_array_mutex); + uloop_timeout_set(&probe_timeout, timeout_config.remove_probe * 1000); +} + +// TODO: Move mutex handling to remove_??? function to make test harness simpler? +// Or not needed as test harness not threaded? +void remove_client_array_cb(struct uloop_timeout* t) { + pthread_mutex_lock(&client_array_mutex); + printf("[Thread] : Removing old client entries!\n"); + remove_old_client_entries(time(0), timeout_config.update_client); + pthread_mutex_unlock(&client_array_mutex); + uloop_timeout_set(&client_timeout, timeout_config.update_client * 1000); +} + +// TODO: Move mutex handling to remove_??? function to make test harness simpler? +// Or not needed as test harness not threaded? +void remove_ap_array_cb(struct uloop_timeout* t) { + pthread_mutex_lock(&ap_array_mutex); + printf("[ULOOP] : Removing old ap entries!\n"); + remove_old_ap_entries(time(0), timeout_config.remove_ap); + pthread_mutex_unlock(&ap_array_mutex); + uloop_timeout_set(&ap_timeout, timeout_config.remove_ap * 1000); +} + +// TODO: Move mutex handling to (new) remove_??? function to make test harness simpler? +// Or not needed as test harness not threaded? +void denied_req_array_cb(struct uloop_timeout* t) { + pthread_mutex_lock(&denied_array_mutex); + printf("[ULOOP] : Processing denied authentication!\n"); + + time_t current_time = time(0); + + int i = 0; + while (i <= denied_req_last) { + // check counter + + //check timer + if (denied_req_array[i].time < current_time - timeout_config.denied_req_threshold) { + + // client is not connected for a given time threshold! + if (!is_connected_somehwere(denied_req_array[i].client_addr)) { + printf("Client has probably a bad driver!\n"); + + // problem that somehow station will land into this list + // maybe delete again? + if (insert_to_maclist(denied_req_array[i].client_addr) == 0) { + send_add_mac(denied_req_array[i].client_addr); + // TODO: File can grow arbitarily large. Resource consumption risk. + // TODO: Consolidate use of file across source: shared resource for name, single point of access? + write_mac_to_file("/tmp/dawn_mac_list", denied_req_array[i].client_addr); + } + } + denied_req_array_delete(denied_req_array[i]); + } + else + { + i++; + } + } + pthread_mutex_unlock(&denied_array_mutex); + uloop_timeout_set(&denied_req_timeout, timeout_config.denied_req_threshold * 1000); +} + + + diff --git a/src/utils/utils.c b/src/utils/utils.c index e2b9c87..8d49abc 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -1,7 +1,6 @@ -#include -#include #include -#include "datastorage.h" +#include + #include "utils.h" int string_is_greater(uint8_t *str, uint8_t *str_2) { @@ -23,73 +22,9 @@ int string_is_greater(uint8_t *str, uint8_t *str_2) { } // source: https://elixir.bootlin.com/linux/v4.9/source/lib/hexdump.c#L28 -int hex_to_bin(char ch) { +int hex_to_dec(char ch) { if ((ch >= '0') && (ch <= '9')) return ch - '0'; ch = tolower(ch); if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10; return -1; } - -// based on: hostapd src/utils/common.c -int hwaddr_aton(const char *txt, uint8_t *addr) { - int i; - - for (i = 0; i < ETH_ALEN; i++) { - int a, b; - - a = hex_to_bin(*txt++); - if (a < 0) return -1; - b = hex_to_bin(*txt++); - if (b < 0) return -1; - *addr++ = (a << 4) | b; - // TODO: Should NUL terminator be checked for? Is aa:bb:cc:dd:ee:ff00 valid input? - if (i < (ETH_ALEN - 1) && *txt++ != ':') return -1; - } - - return 0; -} - -// TODO: Never called in DAWN code. Remove? -#if 0 -/* Convert badly formed MAC addresses with single digit element to double digit -** eg 11:2:33:4:55:6 to 11:02:33:04:55:06 */` -int convert_mac(char *in, char *out) { - int i, j = 0; - - for (i = 0; i < ETH_ALEN; i++) { - /* Do we have a single-digit element? */ - if (in[j + 1] == ':' || in[j + 1] == '\0') { - out[3 * i] = '0'; - out[(3 * i) + 1] = toupper(in[j]); - out[(3 * i) + 2] = toupper(in[j + 1]); - j += 2; - } else { - out[3 * i] = toupper(in[j]); - out[(3 * i) + 1] = toupper(in[j + 1]); - out[(3 * i) + 2] = in[j + 2]; - j += 3; - } - } - return 0; -} -#endif - -void write_mac_to_file(char *path, uint8_t addr[]) { - FILE *f = fopen(path, "a"); - if (f == NULL) { - fprintf(stderr,"Error opening mac file!\n"); - exit(1); - } - - char mac_buf[20]; - sprintf(mac_buf, MACSTR, MAC2STR(addr)); - - fprintf(f, "%s\n", mac_buf); - - fclose(f); -} - -int rcpi_to_rssi(int rcpi) -{ - return rcpi / 2 - 110; -}