diff --git a/files/dawn.config b/files/dawn.config index 95ae816..8cad0b0 100644 --- a/files/dawn.config +++ b/files/dawn.config @@ -1,28 +1,38 @@ -config settings network - option broadcast_ip '10.0.0.255' - option broadcast_port '1025' - option shared_key 'Niiiiiiiiiiiiiik' - option iv 'Niiiiiiiiiiiiiik' +config network + option broadcast_ip '10.0.0.255' + option broadcast_port '1025' + option multicast '0' + option shared_key 'Niiiiiiiiiiiiiik' + option iv 'Niiiiiiiiiiiiiik' -config settings ordering - option sort_order 'csfb' +config ordering + option sort_order 'cbfs' -config settings hostapd - option hostapd_dir '/var/run/hostapd' +config hostapd + option hostapd_dir '/var/run/hostapd' -config settings times - option update_client '50' - option remove_client '120' - option remove_probe '120' +config times + option update_client '10' + option remove_client '15' + option remove_probe '120' + option remove_ap '460' + option update_hostapd '10' -config settings metric - option ht_support '10' - option vht_support '50' - option no_ht_support '0' - option no_vht_support '0' - option rssi '10' - option freq '50' - option chan_util '0' - option max_chan_util '100' - option min_rssi '-60' - option min_probe_count '5' +config metric + option ht_support '10' + option vht_support '100' + option no_ht_support '0' + option no_vht_support '0' + option rssi '0' + option low_rssi '-500' + option freq '100' + option chan_util '0' + option max_chan_util '0' + option rssi_val '-60' + option low_rssi_val '-80' + option chan_util_val '140' + option max_chan_util_val '170' + option min_probe_count '4' + option bandwith_threshold '6' + option use_station_count '1' + option eval_probe_req '1' diff --git a/files/dawn.init b/files/dawn.init index 7bc1f79..8e83253 100755 --- a/files/dawn.init +++ b/files/dawn.init @@ -11,45 +11,10 @@ NAME=dawn start_service() { echo "Starting Service..." - - local broadcast_ip - local broadcast_port - local sort_order - local hostapd_dir - local shared_key - local iv - - config_load "${NAME}" - config_get broadcast_ip network broadcast_ip - config_get broadcast_port network broadcast_port - config_get shared_key network shared_key - config_get iv network iv - - config_get sort_order ordering sort_order - config_get hostapd_dir hostapd hostapd_dir - procd_open_instance - echo "$PROG -p $broadcast_port -i $broadcast_ip -o $sort_order" - procd_set_param command "$PROG" - procd_append_param command -p "${broadcast_port}" - procd_append_param command -i "${broadcast_ip}" - procd_append_param command -o "${sort_order}" - procd_append_param command -h "${hostapd_dir}" - procd_append_param command -k "${shared_key}" - procd_append_param command -v "${iv}" - + procd_set_param command $PROG procd_set_param stdout 1 procd_set_param stderr 1 - - echo "${command}" - - # procd_set_param respawn - - echo "Starting mdns" - procd_add_mdns "dawn" "udp" "${broadcast_port}" "daemon=dawn" "colour=fuschia" - - echo "MDNS Startet" - procd_close_instance echo "Dawn instance started!" } \ No newline at end of file diff --git a/files/mac_list b/files/mac_list new file mode 100644 index 0000000..e69de29 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e484261..c24cb7e 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,46 +8,52 @@ ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -Wmissing-declarations -Wno-unknow SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") SET(SOURCES - main.c + main.c - storage/datastorage.c - include/datastorage.h + storage/datastorage.c + include/datastorage.h - network/networksocket.c - include/networksocket.h + network/networksocket.c + include/networksocket.h - network/broadcastsocket.c - include/broadcastsocket.h + network/broadcastsocket.c + include/broadcastsocket.h - network/multicastsocket.c - include/multicastsocket.h + network/multicastsocket.c + include/multicastsocket.h - utils/ubus.c - include/ubus.h + utils/ubus.c + include/ubus.h - include/utils.h + include/utils.h - utils/runopts.c - include/runopts.h + utils/runopts.c + include/runopts.h - utils/dawn_uci.c - include/dawn_uci.h + utils/dawn_uci.c + include/dawn_uci.h - crypto/crypto.c - include/crypto.h + crypto/crypto.c + include/crypto.h - crypto/base64.c - include/base64.h + crypto/base64.c + include/base64.h - utils/utils.c include/tcpsocket.h network/tcpsocket.c) + utils/utils.c + + include/tcpsocket.h + network/tcpsocket.c + + include/dawn_iwinfo.h + utils/dawn_iwinfo.c) SET(LIBS - ubox ubus json-c blobmsg_json config uci gcrypt ssl crypto) + ubox ubus json-c blobmsg_json config uci gcrypt iwinfo) ADD_EXECUTABLE(dawn ${SOURCES} utils/dawn_uci.c include/dawn_uci.h) TARGET_LINK_LIBRARIES(dawn ${LIBS}) INSTALL(TARGETS dawn - RUNTIME DESTINATION /usr/bin/ -) \ No newline at end of file + RUNTIME DESTINATION /usr/bin/ + ) \ No newline at end of file diff --git a/src/crypto/base64.c b/src/crypto/base64.c index eec7d98..9bed459 100644 --- a/src/crypto/base64.c +++ b/src/crypto/base64.c @@ -88,28 +88,27 @@ /* aaaack but it's fast and const should make it shared text page. */ static const unsigned char pr2six[256] = -{ - /* ASCII table */ - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, - 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, - 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 -}; + { + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 + }; -int Base64decode_len(const char *bufcoded) -{ +int Base64decode_len(const char *bufcoded) { int nbytesdecoded; register const unsigned char *bufin; register int nprbytes; @@ -123,8 +122,7 @@ int Base64decode_len(const char *bufcoded) return nbytesdecoded + 1; } -int Base64decode(char *bufplain, const char *bufcoded) -{ +int Base64decode(char *bufplain, const char *bufcoded) { int nbytesdecoded; register const unsigned char *bufin; register unsigned char *bufout; @@ -139,28 +137,28 @@ int Base64decode(char *bufplain, const char *bufcoded) bufin = (const unsigned char *) bufcoded; while (nprbytes > 4) { - *(bufout++) = - (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); - *(bufout++) = - (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); - *(bufout++) = - (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); - bufin += 4; - nprbytes -= 4; + *(bufout++) = + (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); + *(bufout++) = + (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); + *(bufout++) = + (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); + bufin += 4; + nprbytes -= 4; } /* Note: (nprbytes == 1) would be an error, so just ingore that case */ if (nprbytes > 1) { - *(bufout++) = - (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); + *(bufout++) = + (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); } if (nprbytes > 2) { - *(bufout++) = - (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); + *(bufout++) = + (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); } if (nprbytes > 3) { - *(bufout++) = - (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); + *(bufout++) = + (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); } *(bufout++) = '\0'; @@ -169,39 +167,36 @@ int Base64decode(char *bufplain, const char *bufcoded) } static const char basis_64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -int Base64encode_len(int len) -{ +int Base64encode_len(int len) { return ((len + 2) / 3 * 4) + 1; } -int Base64encode(char *encoded, const char *string, int len) -{ +int Base64encode(char *encoded, const char *string, int len) { int i; char *p; p = encoded; for (i = 0; i < len - 2; i += 3) { - *p++ = basis_64[(string[i] >> 2) & 0x3F]; - *p++ = basis_64[((string[i] & 0x3) << 4) | - ((int) (string[i + 1] & 0xF0) >> 4)]; - *p++ = basis_64[((string[i + 1] & 0xF) << 2) | - ((int) (string[i + 2] & 0xC0) >> 6)]; - *p++ = basis_64[string[i + 2] & 0x3F]; - } - if (i < len) { - *p++ = basis_64[(string[i] >> 2) & 0x3F]; - if (i == (len - 1)) { - *p++ = basis_64[((string[i] & 0x3) << 4)]; - *p++ = '='; - } - else { + *p++ = basis_64[(string[i] >> 2) & 0x3F]; *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; - *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; + *p++ = basis_64[((string[i + 1] & 0xF) << 2) | + ((int) (string[i + 2] & 0xC0) >> 6)]; + *p++ = basis_64[string[i + 2] & 0x3F]; } - *p++ = '='; + if (i < len) { + *p++ = basis_64[(string[i] >> 2) & 0x3F]; + if (i == (len - 1)) { + *p++ = basis_64[((string[i] & 0x3) << 4)]; + *p++ = '='; + } else { + *p++ = basis_64[((string[i] & 0x3) << 4) | + ((int) (string[i + 1] & 0xF0) >> 4)]; + *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; + } + *p++ = '='; } *p++ = '\0'; diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c index ab38eaa..50419d0 100644 --- a/src/crypto/crypto.c +++ b/src/crypto/crypto.c @@ -25,7 +25,7 @@ void gcrypt_init() { } } -void gcrypt_set_key_and_iv(char *key, char *iv) { +void gcrypt_set_key_and_iv(const char *key, const char *iv) { size_t keylen = gcry_cipher_get_algo_keylen(GCRY_CIPHER); size_t blklen = gcry_cipher_get_algo_blklen(GCRY_CIPHER); @@ -59,7 +59,7 @@ void gcrypt_set_key_and_iv(char *key, char *iv) { } // free out buffer after using! -char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int* out_length) { +char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int *out_length) { if (0U != (msg_length & 0xfU)) msg_length += 0x10U - (msg_length & 0xfU); diff --git a/src/include/crypto.h b/src/include/crypto.h index 794186f..fd80314 100644 --- a/src/include/crypto.h +++ b/src/include/crypto.h @@ -9,10 +9,10 @@ char *unbase_64(unsigned char *input, int length); void gcrypt_init(); -void gcrypt_set_key_and_iv(char *key, char *iv); +void gcrypt_set_key_and_iv(const char *key, const char *iv); //char *gcrypt_encrypt_msg(char *msg, size_t msg_length); -char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int* out_length); +char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int *out_length); char *gcrypt_decrypt_msg(char *msg, size_t msg_length); @@ -31,8 +31,11 @@ void build_decoding_table(); void base64_cleanup(); int Base64decode_len(const char *bufcoded); + int Base64encode_len(int len); + int Base64encode(char *encoded, const char *string, int len); + int Base64decode(char *bufplain, const char *bufcoded); diff --git a/src/include/datastorage.h b/src/include/datastorage.h index ff9ed33..dbb2819 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -8,6 +8,8 @@ #include #include #include +#include + #include "tcpsocket.h" @@ -15,31 +17,70 @@ #define ETH_ALEN 6 #endif +/* Mac */ + +// ---------------- Defines ------------------- +#define MAC_LIST_LENGTH 100 + +// ---------------- Structs ---------------- +uint8_t mac_list[MAC_LIST_LENGTH][ETH_ALEN]; + +// ---------------- Functions ---------- +void insert_macs_from_file(); +int insert_to_maclist(uint8_t mac[]); + + +/* Metric */ + struct probe_metric_s dawn_metric; +// ---------------- Structs ---------------- struct probe_metric_s { 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 min_rssi; + int rssi_val; + int low_rssi_val; + int chan_util_val; + int max_chan_util_val; int min_probe_count; + int bandwith_threshold; + int use_station_count; + int eval_probe_req; }; struct time_config_s { time_t update_client; time_t remove_client; time_t remove_probe; + time_t remove_ap; + time_t update_hostapd; }; -#define SORT_NUM 5 -#define TIME_THRESHOLD 120 // every minute +struct network_config_s { + const char* broadcast_ip; + int broadcast_port; + const char* multicast; + const char* shared_key; + const char* iv; + int bool_multicast; +}; -// Probe entrys +struct time_config_s timeout_config; + +// ---------------- Global variables ---------------- +struct probe_metric_s dawn_metric; + + +/* Probe, Auth, Assoc */ + +// ---------------- Structs ---------------- typedef struct probe_entry_s { uint8_t bssid_addr[ETH_ALEN]; uint8_t client_addr[ETH_ALEN]; @@ -60,13 +101,42 @@ typedef struct auth_entry_s { uint32_t freq; } auth_entry; +typedef struct hostapd_notify_entry_s { + uint8_t bssid_addr[ETH_ALEN]; + uint8_t client_addr[ETH_ALEN]; +} hostapd_notify_entry; + typedef struct auth_entry_s assoc_entry; +// ---------------- Defines ---------------- +#define PROBE_ARRAY_LEN 1000 -typedef struct { - uint32_t freq; -} client_request; +#define SSID_MAX_LEN 32 +// ---------------- Global variables ---------------- +struct probe_entry_s probe_array[PROBE_ARRAY_LEN]; +pthread_mutex_t probe_array_mutex; + +// ---------------- Functions ---------------- +probe_entry insert_to_array(probe_entry entry, int inc_counter); + +void probe_array_insert(probe_entry entry); + +probe_entry probe_array_delete(probe_entry entry); + +probe_entry probe_array_get_entry(uint8_t bssid_addr[], uint8_t client_addr[]); + +void print_probe_array(); + +void print_probe_entry(probe_entry entry); + +void print_auth_entry(auth_entry entry); + +void uloop_add_data_cbs(); + +/* AP, Client */ + +// ---------------- Structs ---------------- typedef struct client_s { uint8_t bssid_addr[ETH_ALEN]; uint8_t client_addr[ETH_ALEN]; @@ -94,28 +164,23 @@ typedef struct ap_s { uint8_t vht; uint32_t channel_utilization; time_t time; + uint32_t station_count; + uint8_t ssid[SSID_MAX_LEN]; } ap; -// Array +// ---------------- Defines ---------------- #define ARRAY_AP_LEN 50 #define TIME_THRESHOLD_AP 30 -struct ap_s ap_array[ARRAY_AP_LEN]; -pthread_mutex_t ap_array_mutex; - -ap insert_to_ap_array(ap entry); -void print_ap_array(); -void *remove_ap_array_thread(void *arg); -ap ap_array_get_ap(uint8_t bssid_addr[]); - -// Array #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 client_s client_array[ARRAY_CLIENT_LEN]; pthread_mutex_t client_array_mutex; +struct ap_s ap_array[ARRAY_AP_LEN]; +pthread_mutex_t ap_array_mutex; void print_tcp_array(); @@ -123,6 +188,8 @@ int mac_is_equal(uint8_t addr1[], uint8_t addr2[]); int mac_is_greater(uint8_t addr1[], uint8_t addr2[]); +// ---------------- Functions ---------------- + void insert_client_to_array(client entry); void kick_clients(uint8_t bssid[], uint32_t id); @@ -135,33 +202,37 @@ void print_client_array(); void print_client_entry(client entry); -void *remove_client_array_thread(void *arg); +ap insert_to_ap_array(ap entry); -#define ARRAY_LEN 1000 +void print_ap_array(); -struct probe_entry_s probe_array[ARRAY_LEN]; -pthread_mutex_t probe_array_mutex; +ap ap_array_get_ap(uint8_t bssid_addr[]); -probe_entry insert_to_array(probe_entry entry, int inc_counter); +int build_hearing_map_sort_client(struct blob_buf *b); -void probe_array_insert(probe_entry entry); +int build_network_overview(struct blob_buf *b); -probe_entry probe_array_delete(probe_entry entry); +int probe_array_set_all_probe_count(uint8_t client_addr[], uint32_t probe_count); -probe_entry probe_array_get_entry(uint8_t bssid_addr[], uint8_t client_addr[]); +/* Utils */ -int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]); +// ---------------- Defines ------------------- +#define SORT_NUM 5 +#define TIME_THRESHOLD 120 // every minute -void print_array(); +// ---------------- Global variables ---------------- +char* sort_string; -void print_probe_entry(probe_entry entry); +// ---------------- Functions ------------------- +int mac_is_equal(uint8_t addr1[], uint8_t addr2[]); -void print_auth_entry(auth_entry entry); +int mac_is_greater(uint8_t addr1[], uint8_t addr2[]); -void *remove_array_thread(void *arg); +int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], int automatic_kick); -// List +/* List stuff */ + typedef struct node { probe_entry data; struct node *ptr; @@ -181,7 +252,7 @@ void *remove_thread(void *arg); pthread_mutex_t list_mutex; node *probe_list_head; -char sort_string[SORT_NUM]; + #define ARRAY_NETWORK_LEN 50 struct network_con_s network_array[ARRAY_NETWORK_LEN]; diff --git a/src/include/dawn_iwinfo.h b/src/include/dawn_iwinfo.h new file mode 100644 index 0000000..36cec7a --- /dev/null +++ b/src/include/dawn_iwinfo.h @@ -0,0 +1,15 @@ +#ifndef DAWN_RSSI_H +#define DAWN_RSSI_H + +#include +#include +#include +#include + +int get_rssi_iwinfo(__uint8_t *client_addr); + +int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate); + +int compare_essid_iwinfo(__uint8_t *bssid_addr, __uint8_t *bssid_addr_to_compare); + +#endif //DAWN_RSSI_H diff --git a/src/include/dawn_uci.h b/src/include/dawn_uci.h index b2ee0cf..ed65d52 100644 --- a/src/include/dawn_uci.h +++ b/src/include/dawn_uci.h @@ -5,4 +5,14 @@ struct probe_metric_s uci_get_dawn_metric(); struct time_config_s uci_get_time_config(); +struct network_config_s uci_get_dawn_network(); + +const char* uci_get_dawn_hostapd_dir(); + +const char* uci_get_dawn_sort_order(); + +int uci_init(); + +int uci_clear(); + #endif //DAWN_UCI_H_H diff --git a/src/include/multicastsocket.h b/src/include/multicastsocket.h index fe305e0..3b8e86d 100644 --- a/src/include/multicastsocket.h +++ b/src/include/multicastsocket.h @@ -3,4 +3,6 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_port, struct sockaddr_in *addr); +int remove_multicast_socket(int socket); + #endif diff --git a/src/include/networksocket.h b/src/include/networksocket.h index 5b04f3e..4ab5a23 100644 --- a/src/include/networksocket.h +++ b/src/include/networksocket.h @@ -5,7 +5,7 @@ pthread_mutex_t send_mutex; -int init_socket_runopts(char *_ip, char *_port, int broadcast_socket); +int init_socket_runopts(const char *_ip, int _port, int _multicast_socket); int send_string(char *msg); diff --git a/src/include/ubus.h b/src/include/ubus.h index 295fa28..34067f2 100644 --- a/src/include/ubus.h +++ b/src/include/ubus.h @@ -2,11 +2,11 @@ #define __DAWN_UBUS_H #include +#include + #include "datastorage.h" -#define MIN_PROBE_REQ 2 // TODO: Parse from config file... - -int dawn_init_ubus(const char *ubus_socket, char *hostapd_dir); +int dawn_init_ubus(const char *ubus_socket, const char *hostapd_dir); int parse_to_probe_req(struct blob_attr *msg, probe_entry *prob_req); @@ -16,18 +16,32 @@ int parse_to_assoc_req(struct blob_attr *msg, assoc_entry *assoc_req); int parse_to_clients(struct blob_attr *msg, int do_kick, uint32_t id); +int parse_to_hostapd_notify(struct blob_attr *msg, hostapd_notify_entry *notify_req); + void del_client_interface(uint32_t id, const uint8_t *client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time); void del_client_all_interfaces(const uint8_t *client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time); void *update_clients_thread(void *arg); -void *kick_clients_thread(void *arg); - void *update_connections_thread(void *arg); -char *hostapd_dir_glob; +const char *hostapd_dir_glob; int ubus_call_umdns(); +int ubus_send_probe_via_network(struct probe_entry_s probe_entry); + +void update_hostapd_sockets(struct uloop_timeout *t); + +void add_client_update_timer(time_t time); + +int handle_network_msg(char* msg); + +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); + +int send_set_probe(uint8_t client_addr[]); + #endif diff --git a/src/include/utils.h b/src/include/utils.h index 79f9863..efc874b 100644 --- a/src/include/utils.h +++ b/src/include/utils.h @@ -7,7 +7,16 @@ #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" + int hex_to_bin(char ch); + int hwaddr_aton(const char *txt, uint8_t *addr); +int convert_mac(char *in, char *out); + +void write_mac_to_file(char* path, uint8_t addr[]); + +int string_is_greater(uint8_t* str, uint8_t* str_2); + #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index 5c6c8cc..44d7ddd 100644 --- a/src/main.c +++ b/src/main.c @@ -1,14 +1,8 @@ #include -#include - #include #include -#include -#include #include -#include #include -#include #include "datastorage.h" #include "networksocket.h" @@ -19,42 +13,24 @@ #define BUFSIZE 17 #define BUFSIZE_DIR 256 - #include "crypto.h" - -#define _GNU_SOURCE -#include -#include - -//static void* (*real_malloc)(size_t)=NULL; -//static void* (*real_free)(void *p)=NULL; +#include "dawn_iwinfo.h" void daemon_shutdown(); void signal_handler(int sig); -struct sigaction newSigAction; +int init_mutex(); -//int free_counter = 0; +struct sigaction signal_action; -pthread_t tid_probe; -pthread_t tid_client; -pthread_t tid_get_client; -pthread_t tid_kick_clients; -pthread_t tid_ap; pthread_t tid_tcp_server; pthread_t tid_connections; - -void daemon_shutdown() -{ +void daemon_shutdown() { // kill threads - printf("Cancelling Threads!\n"); - pthread_cancel(tid_probe); - //pthread_cancel(tid_client); - pthread_cancel(tid_get_client); - //pthread_cancel(tid_kick_clients); - //pthread_cancel(tid_ap); - pthread_cancel(tid_connections); + close_socket(); + uci_clear(); + uloop_cancelled = true; // free ressources printf("Freeing mutex ressources\n"); @@ -63,139 +39,27 @@ void daemon_shutdown() pthread_mutex_destroy(&client_array_mutex); pthread_mutex_destroy(&ap_array_mutex); pthread_mutex_destroy(&tcp_array_mutex); - - //printf("Free Counter: %d\n", free_counter); } -void signal_handler(int sig) -{ - printf("SOME SIGNAL RECEIVED!\n"); - switch(sig) - { +void signal_handler(int sig) { + switch (sig) { case SIGHUP: - //syslog(LOG_WARNING, "Received SIGHUP signal."); + daemon_shutdown(); break; case SIGINT: + daemon_shutdown(); + break; case SIGTERM: - //syslog(LOG_INFO, "Daemon exiting"); - //daemonShutdown(); daemon_shutdown(); exit(EXIT_SUCCESS); - break; default: - //syslog(LOG_WARNING, "Unhandled signal %s", strsignal(sig)); + daemon_shutdown(); break; } } -/* -static void mtrace_init(void) + +int init_mutex() { - real_malloc = dlsym(RTLD_NEXT, "malloc"); - if (NULL == real_malloc) { - fprintf(stderr, "Error in `dlsym`: %s\n", dlerror()); - } - real_free = dlsym(RTLD_NEXT, "free"); - if (NULL == real_free) { - fprintf(stderr, "Error in `dlsym`: %s\n", dlerror()); - } -} - -void *malloc(size_t size) -{ - mtrace_init(); - if(real_malloc==NULL) { - mtrace_init(); - } - - void *p = NULL; - fprintf(stderr, "malloc(%d) = ", size); - p = real_malloc(size); - fprintf(stderr, "%p\n", p); - free_counter++; - return p; -} - -void free(void *p) -{ - mtrace_init(); - if(real_free==NULL) { - mtrace_init(); - } - p = real_free(p); - fprintf(stderr, "free: "); - fprintf(stderr, "%p\n", p); - free_counter--; -}*/ - -int main(int argc, char **argv) { - //free_counter = 0; - - const char *ubus_socket = NULL; - int ch; - - char opt_broadcast_ip[BUFSIZE]; - char opt_broadcast_port[BUFSIZE]; - char opt_hostapd_dir[BUFSIZE_DIR]; - - char shared_key[BUFSIZE_DIR]; - char iv[BUFSIZE_DIR]; - - while ((ch = getopt(argc, argv, "cs:p:i:b:o:h:i:k:v:")) != -1) { - switch (ch) { - case 's': - ubus_socket = optarg; - break; - case 'p': - snprintf(opt_broadcast_port, BUFSIZE, "%s", optarg); - printf("broadcast port: %s\n", opt_broadcast_port); - break; - case 'i': - snprintf(opt_broadcast_ip, BUFSIZE, "%s", optarg); - printf("broadcast ip: %s\n", opt_broadcast_ip); - break; - case 'o': - snprintf(sort_string, SORT_NUM, "%s", optarg); - printf("sort string: %s\n", sort_string); - break; - case 'h': - snprintf(opt_hostapd_dir, BUFSIZE_DIR, "%s", optarg); - printf("hostapd dir: %s\n", opt_hostapd_dir); - hostapd_dir_glob = optarg; - break; - case 'k': - snprintf(shared_key, BUFSIZE_DIR, "%s", optarg); - printf("Key: %s\n", shared_key); - break; - case 'v': - snprintf(iv, BUFSIZE_DIR, "%s", optarg); - printf("IV: %s\n", iv); - break; - default: - break; - } - } - - pthread_create(&tid_tcp_server, NULL, &run_tcp_socket, NULL); - - argc -= optind; - argv += optind; - - /* Set up a signal handler */ - newSigAction.sa_handler = signal_handler; - sigemptyset(&newSigAction.sa_mask); - newSigAction.sa_flags = 0; - - /* Signals to handle */ - sigaction(SIGHUP, &newSigAction, NULL); /* catch hangup signal */ - sigaction(SIGTERM, &newSigAction, NULL); /* catch term signal */ - sigaction(SIGINT, &newSigAction, NULL); /* catch interrupt signal */ - - - gcrypt_init(); - gcrypt_set_key_and_iv(shared_key, iv); - - struct time_config_s time_config = uci_get_time_config(); - if (pthread_mutex_init(&list_mutex, NULL) != 0) { printf("\n mutex init failed\n"); return 1; @@ -215,29 +79,46 @@ int main(int argc, char **argv) { printf("\n mutex init failed\n"); return 1; } + return 0; +} - if (pthread_mutex_init(&tcp_array_mutex, NULL) != 0) { - printf("\n mutex init failed\n"); - return 1; - } +int main(int argc, char **argv) { - init_socket_runopts(opt_broadcast_ip, opt_broadcast_port, 1); + const char *ubus_socket = NULL; - pthread_create(&tid_probe, NULL, &remove_array_thread, (void*)&time_config.remove_probe); - pthread_create(&tid_client, NULL, &remove_client_array_thread, (void*)&time_config.remove_client); - pthread_create(&tid_get_client, NULL, &update_clients_thread, (void*)&time_config.update_client); + argc -= optind; + argv += optind; + // connect signals + signal_action.sa_handler = signal_handler; + sigemptyset(&signal_action.sa_mask); + signal_action.sa_flags = 0; + sigaction(SIGHUP, &signal_action, NULL); + sigaction(SIGTERM, &signal_action, NULL); + sigaction(SIGINT, &signal_action, NULL); + + uci_init(); + struct network_config_s net_config = uci_get_dawn_network(); + printf("Broadcst bla: %s\n", net_config.broadcast_ip); + + gcrypt_init(); + gcrypt_set_key_and_iv(net_config.shared_key, net_config.iv); + + struct time_config_s time_config = uci_get_time_config(); + timeout_config = time_config; // TODO: Refactor... + + pthread_create(&tid_tcp_server, NULL, &run_tcp_socket, NULL); pthread_create(&tid_connections, NULL, &update_connections_thread, NULL); + hostapd_dir_glob = uci_get_dawn_hostapd_dir(); + sort_string = (char*) uci_get_dawn_sort_order(); + init_mutex(); - //pthread_create(&tid_kick_clients, NULL, &kick_clients_thread, NULL); - //pthread_create(&tid_ap, NULL, &remove_ap_array_thread, NULL); + init_socket_runopts(net_config.broadcast_ip, net_config.broadcast_port, net_config.bool_multicast); - //pthread_create(&tid, NULL, &remove_thread, NULL); - - dawn_init_ubus(ubus_socket, opt_hostapd_dir); - //free_list(probe_list_head); + insert_macs_from_file(); + dawn_init_ubus(ubus_socket, hostapd_dir_glob); return 0; } \ No newline at end of file diff --git a/src/network/broadcastsocket.c b/src/network/broadcastsocket.c index 152a7d8..7d6fc94 100644 --- a/src/network/broadcastsocket.c +++ b/src/network/broadcastsocket.c @@ -32,10 +32,10 @@ int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_ addr->sin_addr.s_addr = inet_addr(_broadcast_ip); addr->sin_port = htons(_broadcast_port); - if (bind(sock, (struct sockaddr *) addr, sizeof(*addr)) < - 0) { + while (bind(sock, (struct sockaddr *) addr, sizeof(*addr)) < + 0) { fprintf(stderr, "Binding socket failed!\n"); - return -1; + sleep(1); } return sock; } \ No newline at end of file diff --git a/src/network/multicastsocket.c b/src/network/multicastsocket.c index 5fed812..66664f2 100644 --- a/src/network/multicastsocket.c +++ b/src/network/multicastsocket.c @@ -11,7 +11,7 @@ #include "multicastsocket.h" -static struct ip_mreq command; /* static ?! */ +static struct ip_mreq command; int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_port, struct sockaddr_in *addr) { int loop = 1; @@ -19,7 +19,7 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_ memset(addr, 0, sizeof(*addr)); addr->sin_family = AF_INET; - addr->sin_addr.s_addr = htonl (INADDR_ANY); + addr->sin_addr.s_addr = inet_addr(_multicast_ip); addr->sin_port = htons (_multicast_port); if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1) { @@ -57,7 +57,7 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_ command.imr_multiaddr.s_addr = inet_addr(_multicast_ip); command.imr_interface.s_addr = htonl (INADDR_ANY); if (command.imr_multiaddr.s_addr == -1) { - perror("224.0.0.1 ist keine Multicast-Adresse\n"); + perror("Wrong multicast address!\n"); exit(EXIT_FAILURE); } if (setsockopt(sock, @@ -67,4 +67,15 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_ perror("setsockopt:IP_ADD_MEMBERSHIP"); } return sock; +} + +int remove_multicast_socket(int socket) { + if (setsockopt(socket, + IPPROTO_IP, + IP_DROP_MEMBERSHIP, + &command, sizeof(command)) < 0) { + perror("setsockopt:IP_DROP_MEMBERSHIP"); + return -1; + } + return 0; } \ No newline at end of file diff --git a/src/network/networksocket.c b/src/network/networksocket.c index 24fa4a1..2e29d33 100644 --- a/src/network/networksocket.c +++ b/src/network/networksocket.c @@ -29,21 +29,23 @@ const char *ip; unsigned short port; char recv_string[MAX_RECV_STRING + 1]; int recv_string_len; +int multicast_socket; void *receive_msg(void *args); void *receive_msg_enc(void *args); -int init_socket_runopts(char *_ip, char *_port, int broadcast_socket) { +int init_socket_runopts(const char *_ip, int _port, int _multicast_socket) { - port = atoi(_port); + port = _port; ip = _ip; + multicast_socket = _multicast_socket; - if (broadcast_socket) { - sock = setup_broadcast_socket(ip, port, &addr); - } else { + if (multicast_socket) { printf("Settingup multicastsocket!\n"); sock = setup_multicast_socket(ip, port, &addr); + } else { + sock = setup_broadcast_socket(ip, port, &addr); } pthread_t sniffer_thread; @@ -141,42 +143,16 @@ void *receive_msg_enc(void *args) { } //recv_string[recv_string_len] = '\0'; - char* base64_dec_str = malloc(Base64decode_len(recv_string)); + char *base64_dec_str = malloc(Base64decode_len(recv_string)); int base64_dec_length = Base64decode(base64_dec_str, recv_string); + char *dec = gcrypt_decrypt_msg(base64_dec_str, base64_dec_length); - //printf("Free %s: %p\n","base64_dec_str", base64_dec_str); + //printf("NETRWORK RECEIVED: %s\n", dec); + free(base64_dec_str); - - //printf("[WC] Network-Received: %s\n", dec); - - probe_entry prob_req; - struct blob_buf b; - - blob_buf_init(&b, 0); - blobmsg_add_json_from_string(&b, dec); - - char *str; - str = blobmsg_format_json(b.head, true); - - if (str == NULL) { - return 0; - } - - if (strlen(str) <= 0) { - return 0; - } - - if (strstr(str, "clients") != NULL) { - parse_to_clients(b.head, 0, 0); - } else if (strstr(str, "target") != NULL) { - if (parse_to_probe_req(b.head, &prob_req) == 0) { - insert_to_array(prob_req, 0); - } - } - // free encrypted string - //printf("Free %s: %p\n","dec", dec); + handle_network_msg(dec); free(dec); } } @@ -209,12 +185,16 @@ int send_string(char *msg) { int send_string_enc(char *msg) { pthread_mutex_lock(&send_mutex); + + //printf("Sending string: %s\n", msg); + + size_t msglen = strlen(msg); int length_enc; char *enc = gcrypt_encrypt_msg(msg, msglen + 1, &length_enc); - char* base64_enc_str = malloc(Base64encode_len(length_enc)); + char *base64_enc_str = malloc(Base64encode_len(length_enc)); size_t base64_enc_length = Base64encode(base64_enc_str, enc, length_enc); if (sendto(sock, @@ -235,4 +215,9 @@ int send_string_enc(char *msg) { return 0; } -void close_socket() { close(sock); } +void close_socket() { + if (multicast_socket) { + remove_multicast_socket(sock); + } + close(sock); +} diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index 7caa623..181a2e5 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -1,6 +1,11 @@ #include "datastorage.h" +#include +#include + #include "ubus.h" +#include "dawn_iwinfo.h" +#include "utils.h" #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] @@ -38,11 +43,185 @@ int tcp_array_insert(struct network_con_s entry); void print_tcp_entry(struct network_con_s entry); +int probe_array_update_rssi(uint8_t bssid_addr[], uint8_t client_addr[], uint32_t rssi); + +int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]); + +int mac_in_maclist(uint8_t mac[]); + +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); + int probe_entry_last = -1; int client_entry_last = -1; int ap_entry_last = -1; int tcp_entry_last = -1; +int mac_list_entry_last = -1; +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 +}; + +int build_hearing_map_sort_client(struct blob_buf *b) +{ + print_probe_array(); + pthread_mutex_lock(&probe_array_mutex); + + void *client_list, *ap_list, *ssid_list; + char ap_mac_buf[20]; + char client_mac_buf[20]; + + blob_buf_init(b, 0); + int m; + for (m = 0; m <= ap_entry_last; m++) { + printf("COMPARING!\n"); + if(m > 0) + { + if(strcmp((char*)ap_array[m].ssid, (char*)ap_array[m-1].ssid) == 0) + { + continue; + } + } + printf("OPEN TABLE!!!\n"); + ssid_list = blobmsg_open_table(b, (char*)ap_array[m].ssid); + + int i; + for (i = 0; i <= probe_entry_last; i++) { + /*if(!mac_is_equal(ap_array[m].bssid_addr, probe_array[i].bssid_addr)) + { + continue; + }*/ + + ap ap_entry_i = ap_array_get_ap(probe_array[i].bssid_addr); + + if (!mac_is_equal(ap_entry_i.bssid_addr, probe_array[i].bssid_addr)) { + continue; + } + + if(strcmp((char*)ap_entry_i.ssid, (char*)ap_array[m].ssid) != 0) + { + continue; + } + + int k; + sprintf(client_mac_buf, MACSTR, MAC2STR(probe_array[i].client_addr)); + client_list = blobmsg_open_table(b, client_mac_buf); + for (k = i; k <= probe_entry_last; k++) { + ap ap_entry = ap_array_get_ap(probe_array[k].bssid_addr); + + if (!mac_is_equal(ap_entry.bssid_addr, probe_array[k].bssid_addr)) { + continue; + } + + if(strcmp((char*)ap_entry.ssid, (char*)ap_array[m].ssid) != 0) + { + continue; + } + + if (!mac_is_equal(probe_array[k].client_addr, probe_array[i].client_addr)) { + i = k - 1; + break; + } else if(k == probe_entry_last) + { + i = k; + } + + sprintf(ap_mac_buf, MACSTR, MAC2STR(probe_array[k].bssid_addr)); + ap_list = blobmsg_open_table(b, ap_mac_buf); + blobmsg_add_u32(b, "signal", probe_array[k].signal); + blobmsg_add_u32(b, "freq", probe_array[k].freq); + blobmsg_add_u8(b, "ht_support", probe_array[k].ht_support); + blobmsg_add_u8(b, "vht_support", probe_array[k].vht_support); + + + // check if ap entry is available + blobmsg_add_u32(b, "channel_utilization", ap_entry.channel_utilization); + blobmsg_add_u32(b, "num_sta", ap_entry.station_count); + blobmsg_add_u32(b, "ht", ap_entry.ht); + blobmsg_add_u32(b, "vht", ap_entry.vht); + + blobmsg_add_u32(b, "score", eval_probe_metric(probe_array[k])); + blobmsg_close_table(b, ap_list); + } + blobmsg_close_table(b, client_list); + } + blobmsg_close_table(b, ssid_list); + } + pthread_mutex_unlock(&probe_array_mutex); + return 0; +} + +int build_network_overview(struct blob_buf *b) +{ + void *client_list, *ap_list, *ssid_list; + char ap_mac_buf[20]; + char client_mac_buf[20]; + + blob_buf_init(b, 0); + int m; + for (m = 0; m <= ap_entry_last; m++) { + printf("COMPARING!\n"); + if(m > 0) + { + if(strcmp((char*)ap_array[m].ssid, (char*)ap_array[m-1].ssid) == 0) + { + continue; + } + } + + ssid_list = blobmsg_open_table(b, (char*)ap_array[m].ssid); + + int i; + for (i = 0; i <= client_entry_last; i++) { + ap ap_entry_i = ap_array_get_ap(client_array[i].bssid_addr); + + if(strcmp((char*)ap_entry_i.ssid, (char*)ap_array[m].ssid) != 0) + { + continue; + } + int k; + sprintf(ap_mac_buf, MACSTR, MAC2STR(client_array[i].bssid_addr)); + ap_list = blobmsg_open_table(b, ap_mac_buf); + printf("AP MAC BUF: %s\n", ap_mac_buf); + for (k = i; k <= client_entry_last; k++){ + if(!mac_is_equal(client_array[k].bssid_addr, client_array[i].bssid_addr)) + { + i = k - 1; + break; + } else if(k == client_entry_last) + { + i = k; + } + + sprintf(client_mac_buf, MACSTR, MAC2STR(client_array[k].client_addr)); + client_list = blobmsg_open_table(b, client_mac_buf); + blobmsg_add_u32(b, "freq", client_array[k].freq); + blobmsg_add_u32(b, "ht", client_array[k].ht); + blobmsg_add_u32(b, "vht", client_array[k].vht); + blobmsg_close_table(b, client_list); + } + blobmsg_close_table(b, ap_list); + } + blobmsg_close_table(b, ssid_list); + } + return 0; +} +>>>>>>> master int eval_probe_metric(struct probe_entry_s probe_entry) { @@ -51,25 +230,76 @@ int eval_probe_metric(struct probe_entry_s probe_entry) { ap ap_entry = ap_array_get_ap(probe_entry.bssid_addr); // check if ap entry is available - if(mac_is_equal(ap_entry.bssid_addr, probe_entry.bssid_addr)) { - score += probe_entry.ht_support ? dawn_metric.ht_support : 0; + if (mac_is_equal(ap_entry.bssid_addr, probe_entry.bssid_addr)) { + score += probe_entry.ht_support && ap_entry.ht ? dawn_metric.ht_support : 0; score += !probe_entry.ht_support && !ap_entry.ht ? dawn_metric.no_ht_support : 0; - score += probe_entry.vht_support ? dawn_metric.vht_support : 0; + score += probe_entry.vht_support && ap_entry.vht ? dawn_metric.vht_support : 0; score += !probe_entry.vht_support && !ap_entry.vht ? dawn_metric.no_vht_support : 0; - score += ap_entry.channel_utilization <= dawn_metric.max_chan_util ? dawn_metric.chan_util : 0; + 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; } score += (probe_entry.freq > 5000) ? dawn_metric.freq : 0; - score += (probe_entry.signal >= dawn_metric.min_rssi) ? dawn_metric.rssi : 0; + 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; - printf("SCORE: %d\n", score); + if(score < 0) + score = -2; // -1 already used... + + printf("SCORE: %d of:\n", score); print_probe_entry(probe_entry); return score; } -int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]) -{ +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); + + if (mac_is_equal(ap_entry_own.bssid_addr, bssid_addr_own) && + mac_is_equal(ap_entry_to_compre.bssid_addr, bssid_addr_to_compare)) + { + return (strcmp((char*)ap_entry_own.ssid, (char*)ap_entry_to_compre.ssid) == 0); + } + return 0; +} + +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); + ap ap_entry_to_compre = ap_array_get_ap(bssid_addr_to_compare); + + // check if ap entry is available + if (mac_is_equal(ap_entry_own.bssid_addr, bssid_addr_own) + && mac_is_equal(ap_entry_to_compre.bssid_addr, bssid_addr_to_compare) + ) { + printf("Comparing own %d to %d\n", ap_entry_own.station_count, ap_entry_to_compre.station_count); + + + int sta_count = ap_entry_own.station_count; + int sta_count_to_compare = ap_entry_to_compre.station_count; + if(is_connected(bssid_addr_own, client_addr)) + { + printf("OWN IS ALREADY CONNECTED! DECREASE COUNTER!!!\n"); + sta_count--; + } + + if(is_connected(bssid_addr_to_compare, client_addr)) + { + printf("COMPARE IS ALREADY CONNECTED! DECREASE COUNTER!!!\n"); + sta_count_to_compare--; + } + printf("AFTER: Comparing own %d to %d\n", sta_count, sta_count_to_compare); + + return sta_count > sta_count_to_compare; + } + + return 0; +} + + +int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], int automatic_kick) { int own_score = -1; // find first client entry in probe array @@ -90,38 +320,71 @@ int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]) break; } if (mac_is_equal(bssid_addr, probe_array[j].bssid_addr)) { + printf("Calculating own score!\n"); own_score = eval_probe_metric(probe_array[j]); break; } } // no entry for own ap - if(own_score == -1) - { + if (own_score == -1) { return -1; } int k; for (k = i; k <= probe_entry_last; k++) { + int score_to_compare; + if (!mac_is_equal(probe_array[k].client_addr, client_addr)) { break; } - if (!mac_is_equal(bssid_addr, probe_array[k].bssid_addr) && - own_score < eval_probe_metric(probe_array[k])) // that's wrong! find client_entry OR write things in probe array struct! + + if (mac_is_equal(bssid_addr, probe_array[k].bssid_addr)) { + printf("Own Score! Skipping!\n"); + print_probe_entry(probe_array[k]); + continue; + } + + // check if same ssid! + if(!compare_ssid(bssid_addr, probe_array[k].bssid_addr)) { + continue; + } + + + printf("Calculating score to compare!\n"); + score_to_compare = eval_probe_metric(probe_array[k]); + + if (own_score < score_to_compare) { return 1; } + if (dawn_metric.use_station_count && own_score == score_to_compare) { + + // only compare if score is bigger or euqal 0 + if(own_score >= 0) { + + // if ap have same value but station count is different... + if (compare_station_count(bssid_addr, probe_array[k].bssid_addr, probe_array[k].client_addr, + automatic_kick)) { + return 1; + } + } + } } return 0; } int kick_client(struct client_s client_entry) { - return better_ap_available(client_entry.bssid_addr, client_entry.client_addr); + return !mac_in_maclist(client_entry.client_addr) && better_ap_available(client_entry.bssid_addr, client_entry.client_addr, 1); } void kick_clients(uint8_t bssid[], uint32_t id) { pthread_mutex_lock(&client_array_mutex); pthread_mutex_lock(&probe_array_mutex); + printf("-------- KICKING CLIENS!!!---------\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; @@ -137,56 +400,105 @@ void kick_clients(uint8_t bssid[], uint32_t id) { if (!mac_is_equal(client_array[j].bssid_addr, bssid)) { break; } - if (kick_client(client_array[j]) > 0) { - // TODO: Better debug output - printf("KICKING CLIENT!!!!!!!!!!!!!\n"); - del_client_interface(id, client_array[j].client_addr, 5, 1, 60000); - } else if (kick_client(client_array[j]) == -1) { - printf("Force client to reconnect!!!!!!!!!!!!!\n"); + + // update rssi + int rssi = get_rssi_iwinfo(client_array[j].client_addr); + if (rssi != INT_MIN) { + pthread_mutex_unlock(&probe_array_mutex); + if (!probe_array_update_rssi(client_array[j].bssid_addr, client_array[j].client_addr, rssi)) { + printf("Failed to update RSSI!\n"); + } else { + printf("RSSI UPDATED: RSSI: %d\n\n", rssi); + } + pthread_mutex_lock(&probe_array_mutex); + + } + + int do_kick = kick_client(client_array[j]); + + // better ap available + if (do_kick > 0) { + 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.bandwith_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); + + del_client_interface(id, client_array[j].client_addr, 5, 1, 1000); + 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, 0, 0); + + // ap is best } else { - printf("STAAAY CLIENT!!!!!!!!!!!!!\n"); + printf("AP is best. Client will stay:\n"); + print_client_entry(client_array[j]); } } + printf("---------------------------\n"); + pthread_mutex_unlock(&probe_array_mutex); pthread_mutex_unlock(&client_array_mutex); } +int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]) { + int i; + int found_in_array = 0; + + if (client_entry_last == -1) { + return 0; + } + + for (i = 0; i <= client_entry_last; i++) { + + if (mac_is_equal(bssid_addr, client_array[i].bssid_addr) && + mac_is_equal(client_addr, client_array[i].client_addr)) { + found_in_array = 1; + break; + } + } + return found_in_array; +} + int client_array_go_next_help(char sort_order[], int i, client entry, client next_entry) { switch (sort_order[i]) { // bssid-mac case 'b': - return mac_is_greater(entry.bssid_addr, next_entry.bssid_addr) && - mac_is_equal(entry.client_addr, next_entry.client_addr); - break; - + return mac_is_greater(entry.bssid_addr, next_entry.bssid_addr); // client-mac case 'c': - return mac_is_greater(entry.client_addr, next_entry.client_addr); - break; - - // frequency - // mac is 5 ghz or 2.4 ghz? - // case 'f': - // return //entry.freq < next_entry.freq && - // entry.freq < 5000 && - // next_entry.freq >= 5000 && - // //entry.freq < 5 && - // mac_is_equal(entry.client_addr, next_entry.client_addr); - // break; - - // signal strength (RSSI) - //case 's': - // return entry.signal < next_entry.signal && - // mac_is_equal(entry.client_addr, next_entry.client_addr); - // break; - + return mac_is_greater(entry.client_addr, next_entry.client_addr) && + mac_is_equal(entry.bssid_addr, next_entry.bssid_addr); default: - return 0; break; } + return 0; } int client_array_go_next(char sort_order[], int i, client entry, @@ -242,7 +554,7 @@ client *client_array_delete(client entry) { } } - for (int j = i; j <= client_entry_last; j++) { + for (int j = i; j < client_entry_last; j++) { client_array[j] = client_array[j + 1]; } @@ -267,13 +579,13 @@ void probe_array_insert(probe_entry entry) { } } for (int j = probe_entry_last; j >= i; j--) { - if (j + 1 <= ARRAY_LEN) { + if (j + 1 <= PROBE_ARRAY_LEN) { probe_array[j + 1] = probe_array[j]; } } probe_array[i] = entry; - if (probe_entry_last < ARRAY_LEN) { + if (probe_entry_last < PROBE_ARRAY_LEN) { probe_entry_last++; } } @@ -296,7 +608,7 @@ probe_entry probe_array_delete(probe_entry entry) { } } - for (int j = i; j <= probe_entry_last; j++) { + for (int j = i; j < probe_entry_last; j++) { probe_array[j] = probe_array[j + 1]; } @@ -306,6 +618,53 @@ probe_entry probe_array_delete(probe_entry entry) { return tmp; } +int probe_array_set_all_probe_count(uint8_t client_addr[], uint32_t probe_count) { + + int updated = 0; + + if (probe_entry_last == -1) { + return 0; + } + + pthread_mutex_lock(&probe_array_mutex); + for (int i = 0; i <= probe_entry_last; i++) { + if (mac_is_equal(client_addr, probe_array[i].client_addr)) { + printf("SETTING MAC!!!\n"); + probe_array[i].counter = probe_count; + }else if(!mac_is_greater(client_addr, probe_array[i].client_addr)) + { + printf("MAC NOT FOUND!!!\n"); + break; + } + } + pthread_mutex_unlock(&probe_array_mutex); + + return updated; +} + +int probe_array_update_rssi(uint8_t bssid_addr[], uint8_t client_addr[], uint32_t rssi) { + + int updated = 0; + + if (probe_entry_last == -1) { + return 0; + } + + + pthread_mutex_lock(&probe_array_mutex); + for (int i = 0; i <= probe_entry_last; i++) { + if (mac_is_equal(bssid_addr, probe_array[i].bssid_addr) && + mac_is_equal(client_addr, probe_array[i].client_addr)) { + probe_array[i].signal = rssi; + updated = 1; + ubus_send_probe_via_network(probe_array[i]); + } + } + pthread_mutex_unlock(&probe_array_mutex); + + return updated; +} + probe_entry probe_array_get_entry(uint8_t bssid_addr[], uint8_t client_addr[]) { int i; @@ -328,7 +687,7 @@ probe_entry probe_array_get_entry(uint8_t bssid_addr[], uint8_t client_addr[]) { return tmp; } -void print_array() { +void print_probe_array() { printf("------------------\n"); printf("Probe Entry Last: %d\n", probe_entry_last); for (int i = 0; i <= probe_entry_last; i++) { @@ -375,23 +734,16 @@ ap insert_to_ap_array(ap entry) { ap ap_array_get_ap(uint8_t bssid_addr[]) { ap ret; - char bssid_mac_string[20]; - sprintf(bssid_mac_string, "%x:%x:%x:%x:%x:%x", MAC2STR(bssid_addr)); - printf("Try to find: %s\n", bssid_mac_string); - printf("in\n"); - print_ap_array(); - if (ap_entry_last == -1) { return ret; } - - pthread_mutex_lock(&ap_array_mutex); int i; for (i = 0; i <= ap_entry_last; i++) { - if (mac_is_equal(bssid_addr, ap_array[i].bssid_addr) || mac_is_greater(ap_array[i].bssid_addr, bssid_addr )) { + if (mac_is_equal(bssid_addr, ap_array[i].bssid_addr)){ + //|| mac_is_greater(ap_array[i].bssid_addr, bssid_addr)) { break; } } @@ -410,9 +762,15 @@ void ap_array_insert(ap entry) { int i; for (i = 0; i <= ap_entry_last; i++) { - if (!mac_is_greater(entry.bssid_addr, ap_array[i].bssid_addr)) { + if (mac_is_greater(entry.bssid_addr, ap_array[i].bssid_addr) && + strcmp((char*)entry.ssid, (char*)ap_array[i].ssid) == 0) { + continue; + } + + if(!string_is_greater(entry.ssid, ap_array[i].ssid)){ break; } + } for (int j = ap_entry_last; j >= i; j--) { if (j + 1 <= ARRAY_AP_LEN) { @@ -443,7 +801,7 @@ ap ap_array_delete(ap entry) { } } - for (int j = i; j <= ap_entry_last; j++) { + for (int j = i; j < ap_entry_last; j++) { ap_array[j] = ap_array[j + 1]; } @@ -454,7 +812,7 @@ ap ap_array_delete(ap entry) { } void remove_old_client_entries(time_t current_time, long long int threshold) { - for (int i = 0; i < probe_entry_last; i++) { + for (int i = 0; i <= client_entry_last; i++) { if (client_array[i].time < current_time - threshold) { client_array_delete(client_array[i]); } @@ -462,58 +820,50 @@ void remove_old_client_entries(time_t current_time, long long int threshold) { } void remove_old_probe_entries(time_t current_time, long long int threshold) { - for (int i = 0; i < probe_entry_last; i++) { + for (int i = 0; i <= probe_entry_last; i++) { if (probe_array[i].time < current_time - threshold) { - probe_array_delete(probe_array[i]); + if (!is_connected(probe_array[i].bssid_addr, probe_array[i].client_addr)) + probe_array_delete(probe_array[i]); } } } void remove_old_ap_entries(time_t current_time, long long int threshold) { - for (int i = 0; i < probe_entry_last; i++) { + for (int i = 0; i <= ap_entry_last; i++) { if (ap_array[i].time < current_time - threshold) { ap_array_delete(ap_array[i]); } } } -void *remove_array_thread(void *arg) { - printf("Removing thread with time: %lu\n", *(long int*)arg); - time_t time_treshold = *(time_t*)arg; - while (1) { - sleep(time_treshold); - pthread_mutex_lock(&probe_array_mutex); - printf("[Thread] : Removing old entries!\n"); - remove_old_probe_entries(time(0), time_treshold); - pthread_mutex_unlock(&probe_array_mutex); - } - return 0; +void uloop_add_data_cbs() { + uloop_timeout_add(&probe_timeout); + uloop_timeout_add(&client_timeout); + uloop_timeout_add(&ap_timeout); } -void *remove_client_array_thread(void *arg) { - time_t time_treshold_client = *(time_t*)arg; - printf("Removing client thread with time: %lu\n", time_treshold_client); - while (1) { - sleep(time_treshold_client); - pthread_mutex_lock(&client_array_mutex); - printf("[Thread] : Removing old client entries!\n"); - remove_old_client_entries(time(0), time_treshold_client); - pthread_mutex_unlock(&client_array_mutex); - } - return 0; +void remove_probe_array_cb(struct uloop_timeout *t) { + pthread_mutex_lock(&probe_array_mutex); + printf("[Thread] : Removing old entries!\n"); + remove_old_probe_entries(time(0), timeout_config.remove_probe); + pthread_mutex_unlock(&probe_array_mutex); + uloop_timeout_set(&probe_timeout, timeout_config.remove_probe * 1000); } -void *remove_ap_array_thread(void *arg) { - time_t time_treshold_ap = *(time_t*)arg; - printf("Removing ap thread with time: %lu\n", time_treshold_ap); - while (1) { - sleep(time_treshold_ap); - pthread_mutex_lock(&ap_array_mutex); - printf("[Thread] : Removing old ap entries!\n"); - remove_old_ap_entries(time(0), time_treshold_ap); - pthread_mutex_unlock(&ap_array_mutex); - } - return 0; +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 insert_client_to_array(client entry) { @@ -526,6 +876,81 @@ void insert_client_to_array(client entry) { pthread_mutex_unlock(&client_array_mutex); } +void insert_macs_from_file() +{ + FILE * fp; + char * line = NULL; + size_t len = 0; + ssize_t read; + + fp = fopen("/etc/dawn/mac_list", "r"); + if (fp == NULL) + exit(EXIT_FAILURE); + + while ((read = getline(&line, &len, fp)) != -1) { + printf("Retrieved line of length %zu :\n", read); + printf("%s", line); + + int tmp_int_mac[ETH_ALEN]; + sscanf(line, MACSTR, STR2MAC(tmp_int_mac)); + + mac_list_entry_last++; + for (int i = 0; i < ETH_ALEN; ++i) { + mac_list[mac_list_entry_last][i] = (uint8_t) tmp_int_mac[i]; + } + } + + printf("Printing MAC List:\n"); + for(int i = 0; i <= mac_list_entry_last; i++) + { + char mac_buf_target[20]; + sprintf(mac_buf_target, MACSTR, MAC2STR(mac_list[i])); + printf("%d: %s\n", i, mac_buf_target); + } + + fclose(fp); + if (line) + free(line); + //exit(EXIT_SUCCESS); +} + +int insert_to_maclist(uint8_t mac[]) +{ + if(mac_in_maclist(mac)) + { + return -1; + } + + mac_list_entry_last++; + for (int i = 0; i < ETH_ALEN; ++i) { + mac_list[mac_list_entry_last][i] = mac[i]; + } + + return 0; +} + + +int mac_in_maclist(uint8_t mac[]) +{ + for(int i = 0; i <= mac_list_entry_last; i++) + { + if(mac_is_equal(mac, mac_list[i])) + { + return 1; + } + } + return 0; +} + + + + + + + + + + node *delete_probe_req(node **ret_remove, node *head, uint8_t bssid_addr[], uint8_t client_addr[]); @@ -839,9 +1264,9 @@ void print_probe_entry(probe_entry entry) { char mac_buf_client[20]; char mac_buf_target[20]; - sprintf(mac_buf_ap, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.bssid_addr)); - sprintf(mac_buf_client, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.client_addr)); - sprintf(mac_buf_target, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.target_addr)); + sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr)); + 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: " @@ -854,9 +1279,9 @@ void print_auth_entry(auth_entry entry) { char mac_buf_client[20]; char mac_buf_target[20]; - sprintf(mac_buf_ap, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.bssid_addr)); - sprintf(mac_buf_client, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.client_addr)); - sprintf(mac_buf_target, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.target_addr)); + sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr)); + 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: " @@ -868,8 +1293,8 @@ void print_client_entry(client entry) { char mac_buf_ap[20]; char mac_buf_client[20]; - sprintf(mac_buf_ap, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.bssid_addr)); - sprintf(mac_buf_client, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.client_addr)); + sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr)); + sprintf(mac_buf_client, MACSTR, MAC2STR(entry.client_addr)); printf("bssid_addr: %s, client_addr: %s, freq: %d, ht_supported: %d, vht_supported: %d, ht: %d, vht: %d\n", mac_buf_ap, mac_buf_client, entry.freq, entry.ht_supported, entry.vht_supported, entry.ht, entry.vht); @@ -887,9 +1312,9 @@ void print_client_array() { void print_ap_entry(ap entry) { char mac_buf_ap[20]; - sprintf(mac_buf_ap, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.bssid_addr)); - printf("bssid_addr: %s, freq: %d, ht: %d, vht: %d, chan_utilz: %d\n", - mac_buf_ap, entry.freq, entry.ht, entry.vht, entry.channel_utilization); + sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr)); + printf("ssid: %s, bssid_addr: %s, freq: %d, ht: %d, vht: %d, chan_utilz: %d\n", + entry.ssid, mac_buf_ap, entry.freq, entry.ht, entry.vht, entry.channel_utilization); } void print_ap_array() { diff --git a/src/utils/dawn_iwinfo.c b/src/utils/dawn_iwinfo.c new file mode 100644 index 0000000..29b55cd --- /dev/null +++ b/src/utils/dawn_iwinfo.c @@ -0,0 +1,197 @@ +#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] + +int call_iwinfo(char *client_addr); + +int parse_rssi(char *iwinfo_string); + +int get_rssi(const char *ifname, uint8_t *client_addr); + +int get_bandwidth(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate); + +#define IWINFO_BUFSIZE 24 * 1024 + +#define IWINFO_ESSID_MAX_SIZE 32 + + +int compare_essid_iwinfo(__uint8_t *bssid_addr, __uint8_t *bssid_addr_to_compare) +{ + const struct iwinfo_ops *iw; + + char mac_buf[20]; + char mac_buf_to_compare[20]; + sprintf(mac_buf, MACSTR, MAC2STR(bssid_addr)); + sprintf(mac_buf_to_compare, MACSTR, MAC2STR(bssid_addr_to_compare)); + + DIR *dirp; + struct dirent *entry; + dirp = opendir(hostapd_dir_glob); // error handling? + if (!dirp) { + fprintf(stderr, "No hostapd sockets!\n"); + return 0; + } + + char* essid = NULL; + char* essid_to_compare = NULL; + + char buf_essid[IWINFO_ESSID_MAX_SIZE+1] = { 0 }; + char buf_essid_to_compare[IWINFO_ESSID_MAX_SIZE+1] = { 0 }; + + while ((entry = readdir(dirp)) != NULL && (essid == NULL || essid_to_compare == NULL)) { + if (entry->d_type == DT_SOCK) { + + iw = iwinfo_backend(entry->d_name); + + static char buf_bssid[18] = { 0 }; + if (iw->bssid(entry->d_name, buf_bssid)) + snprintf(buf_bssid, sizeof(buf_bssid), "00:00:00:00:00:00"); + + if(strcmp(mac_buf, buf_bssid) == 0) + { + + if (iw->ssid(entry->d_name, buf_essid)) + memset(buf_essid, 0, sizeof(buf_essid)); + essid = buf_essid; + } + + if(strcmp(mac_buf_to_compare, buf_bssid) == 0) + { + if (iw->ssid(entry->d_name, buf_essid_to_compare)) + memset(buf_essid_to_compare, 0, sizeof(buf_essid_to_compare)); + essid_to_compare = buf_essid_to_compare; + } + } + } + closedir(dirp); + + printf("Comparing: %s with %s\n", essid, essid_to_compare); + + if(essid == NULL || essid_to_compare == NULL) + { + return -1; + } + + if(strcmp(essid, essid_to_compare) == 0) + { + return 0; + } + + return -1; +} + +int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate) { + + DIR *dirp; + struct dirent *entry; + dirp = opendir(hostapd_dir_glob); // error handling? + if (!dirp) { + fprintf(stderr, "No hostapd sockets!\n"); + return 0; + } + + int sucess = 0; + + while ((entry = readdir(dirp)) != NULL) { + if (entry->d_type == DT_SOCK) { + if (get_bandwidth(entry->d_name, client_addr, rx_rate, tx_rate)) { + sucess = 1; + break; + } + } + } + closedir(dirp); + return sucess; +} + +int get_bandwidth(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate) { + + int i, len; + char buf[IWINFO_BUFSIZE]; + struct iwinfo_assoclist_entry *e; + const struct iwinfo_ops *iw; + + iw = iwinfo_backend(ifname); + + if (iw->assoclist(ifname, buf, &len)) { + printf("No information available\n"); + return 0; + } else if (len <= 0) { + printf("No station connected\n"); + return 0; + } + + for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) { + e = (struct iwinfo_assoclist_entry *) &buf[i]; + + if (mac_is_equal(client_addr, e->mac)) { + //struct iwinfo_assoclist_entry * rx_rate = e->rx_rate; + //struct iwinfo_assoclist_entry * tx_rate = e->tx_rate; + *rx_rate = e->rx_rate.rate / 1000; + *tx_rate = e->tx_rate.rate / 1000; + return 1; + } + // return e->signal; + + + } + + return 0; +} + +int get_rssi_iwinfo(__uint8_t *client_addr) { + + DIR *dirp; + struct dirent *entry; + dirp = opendir(hostapd_dir_glob); // error handling? + if (!dirp) { + fprintf(stderr, "No hostapd sockets!\n"); + return INT_MIN; + } + + int rssi = INT_MIN; + + while ((entry = readdir(dirp)) != NULL) { + if (entry->d_type == DT_SOCK) { + rssi = get_rssi(entry->d_name, client_addr); + if (rssi != INT_MIN) + break; + } + } + closedir(dirp); + return rssi; +} + +int get_rssi(const char *ifname, uint8_t *client_addr) { + + int i, len; + char buf[IWINFO_BUFSIZE]; + struct iwinfo_assoclist_entry *e; + const struct iwinfo_ops *iw; + + iw = iwinfo_backend(ifname); + + if (iw->assoclist(ifname, buf, &len)) { + printf("No information available\n"); + return INT_MIN; + } else if (len <= 0) { + printf("No station connected\n"); + return INT_MIN; + } + + for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) { + e = (struct iwinfo_assoclist_entry *) &buf[i]; + + if (mac_is_equal(client_addr, e->mac)) + return e->signal; + } + + return INT_MIN; +} \ No newline at end of file diff --git a/src/utils/dawn_uci.c b/src/utils/dawn_uci.c index 3d3a06c..71cdde3 100644 --- a/src/utils/dawn_uci.c +++ b/src/utils/dawn_uci.c @@ -4,159 +4,155 @@ #include "dawn_uci.h" -/* -dawn.metric.ht_support -dawn.metric.vht_support' -dawn.metric.rssi -dawn.metric.freq +static struct uci_context *uci_ctx; +static struct uci_package *uci_pkg; - */ - -/* - config settings times - option update_client '50' - option remove_client '120' - option remove_probe '120' - */ - -struct time_config_s uci_get_time_config() +// why is this not included in uci lib...?! +// fund here: https://github.com/br101/pingcheck/blob/master/uci.c +static int uci_lookup_option_int(struct uci_context *uci, struct uci_section *s, + const char *name) { + const char* str = uci_lookup_option_string(uci, s, name); + return str == NULL ? -1 : atoi(str); +} + +struct time_config_s uci_get_time_config() { struct time_config_s ret; - struct uci_context *c; - struct uci_ptr ptr; + printf("Loading Times!"); - c = uci_alloc_context (); + struct uci_element *e; + uci_foreach_element(&uci_pkg->sections, e) { + struct uci_section *s = uci_to_section(e); - printf("Loading TImes!"); - - - char tmp_update_client[] = "dawn.times.update_client"; - if (uci_lookup_ptr (c, &ptr, tmp_update_client, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; + if (strcmp(s->type, "times") == 0) + { + ret.update_client = uci_lookup_option_int(uci_ctx, s, "update_client"); + ret.remove_client = uci_lookup_option_int(uci_ctx, s, "remove_client"); + ret.remove_probe = uci_lookup_option_int(uci_ctx, s, "remove_probe"); + ret.update_hostapd = uci_lookup_option_int(uci_ctx, s, "update_hostapd"); + ret.remove_ap = uci_lookup_option_int(uci_ctx, s, "remove_ap"); + return ret; + } } - if(ptr.o->type == UCI_TYPE_STRING) - ret.update_client = atoi(ptr.o->v.string); - - char tmp_remove_client[] = "dawn.times.remove_client"; - if (uci_lookup_ptr (c, &ptr, tmp_remove_client, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.remove_client = atoi(ptr.o->v.string); - - char tmp_remove_probe[] = "dawn.times.remove_probe"; - if (uci_lookup_ptr (c, &ptr, tmp_remove_probe, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.remove_probe = atoi(ptr.o->v.string); - - printf("Times: %lu, %lu, %lu\n", ret.update_client, ret.remove_client, ret.remove_probe); - - uci_free_context(c); return ret; } -struct probe_metric_s uci_get_dawn_metric() -{ +struct probe_metric_s uci_get_dawn_metric() { struct probe_metric_s ret; - struct uci_context *c; - struct uci_ptr ptr; + struct uci_element *e; + uci_foreach_element(&uci_pkg->sections, e) { + struct uci_section *s = uci_to_section(e); - c = uci_alloc_context (); - - char tmp_ht_support[] = "dawn.metric.ht_support"; - if (uci_lookup_ptr (c, &ptr, tmp_ht_support, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; + if (strcmp(s->type, "metric") == 0) + { + ret.ht_support = uci_lookup_option_int(uci_ctx, s, "ht_support"); + ret.vht_support = uci_lookup_option_int(uci_ctx, s, "vht_support"); + ret.no_ht_support = uci_lookup_option_int(uci_ctx, s, "no_ht_support"); + ret.no_vht_support = uci_lookup_option_int(uci_ctx, s, "no_vht_support"); + ret.rssi = uci_lookup_option_int(uci_ctx, s, "rssi"); + ret.freq = uci_lookup_option_int(uci_ctx, s, "freq"); + ret.rssi_val = uci_lookup_option_int(uci_ctx, s, "rssi_val"); + ret.chan_util = uci_lookup_option_int(uci_ctx, s, "chan_util"); + ret.max_chan_util = uci_lookup_option_int(uci_ctx, s, "max_chan_util"); + ret.chan_util_val = uci_lookup_option_int(uci_ctx, s, "chan_util_val"); + ret.max_chan_util_val = uci_lookup_option_int(uci_ctx, s, "max_chan_util_val"); + ret.min_probe_count = uci_lookup_option_int(uci_ctx, s, "min_probe_count"); + ret.low_rssi = uci_lookup_option_int(uci_ctx, s, "low_rssi"); + ret.low_rssi_val = uci_lookup_option_int(uci_ctx, s, "low_rssi_val"); + ret.bandwith_threshold = uci_lookup_option_int(uci_ctx, s, "bandwith_threshold"); + ret.use_station_count = uci_lookup_option_int(uci_ctx, s, "use_station_count"); + ret.eval_probe_req = uci_lookup_option_int(uci_ctx, s, "eval_probe_req"); + return ret; + } } - if(ptr.o->type == UCI_TYPE_STRING) - ret.ht_support = atoi(ptr.o->v.string); - - char tmp_vht_support[] = "dawn.metric.vht_support"; - if (uci_lookup_ptr (c, &ptr, tmp_vht_support, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.vht_support = atoi(ptr.o->v.string); - - char tmp_no_ht_support[] = "dawn.metric.no_ht_support"; - if (uci_lookup_ptr (c, &ptr, tmp_no_ht_support, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.no_ht_support = atoi(ptr.o->v.string); - - char tmp_no_vht_support[] = "dawn.metric.no_vht_support"; - if (uci_lookup_ptr (c, &ptr, tmp_no_vht_support, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.no_vht_support = atoi(ptr.o->v.string); - - char tmp_rssi[] = "dawn.metric.rssi"; - if (uci_lookup_ptr (c, &ptr, tmp_rssi, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.rssi = atoi(ptr.o->v.string); - - char tmp_freq[] = "dawn.metric.freq"; - if (uci_lookup_ptr (c, &ptr, tmp_freq, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.freq = atoi(ptr.o->v.string); - - char tmp_util[] = "dawn.metric.chan_util"; - if (uci_lookup_ptr (c, &ptr, tmp_util, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.chan_util = atoi(ptr.o->v.string); - - char tmp_min_rssi[] = "dawn.metric.min_rssi"; - if (uci_lookup_ptr (c, &ptr, tmp_min_rssi, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.min_rssi = atoi(ptr.o->v.string); - - char tmp_max_chan_util[] = "dawn.metric.max_chan_util"; - if (uci_lookup_ptr (c, &ptr, tmp_max_chan_util, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.max_chan_util = atoi(ptr.o->v.string); - - - printf("Try to load min_probe_count\n"); - char tmp_min_probe_count[] = "dawn.metric.min_probe_count"; - if (uci_lookup_ptr (c, &ptr, tmp_min_probe_count, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if(ptr.o->type == UCI_TYPE_STRING) - ret.min_probe_count = atoi(ptr.o->v.string); - - printf("Loaded metric: %d\n", ret.min_probe_count); - - uci_free_context(c); return ret; +} + +struct network_config_s uci_get_dawn_network() { + struct network_config_s ret; + + struct uci_element *e; + uci_foreach_element(&uci_pkg->sections, e) { + struct uci_section *s = uci_to_section(e); + + if (strcmp(s->type, "network") == 0) + { + printf("Fronund network entry!\n"); + ret.broadcast_ip = uci_lookup_option_string(uci_ctx, s, "broadcast_ip"); + printf("BROADCAST: %s\n", ret.broadcast_ip); + ret.broadcast_port = uci_lookup_option_int(uci_ctx, s, "broadcast_port"); + ret.bool_multicast = uci_lookup_option_int(uci_ctx, s, "multicast"); + printf("multicast: %s\n", ret.broadcast_ip); + ret.shared_key = uci_lookup_option_string(uci_ctx, s, "shared_key"); + ret.iv = uci_lookup_option_string(uci_ctx, s, "iv"); + return ret; + } + } + + return ret; +} +const char* uci_get_dawn_hostapd_dir() { + struct uci_element *e; + uci_foreach_element(&uci_pkg->sections, e) + { + struct uci_section *s = uci_to_section(e); + + if (strcmp(s->type, "hostapd") == 0) { + return uci_lookup_option_string(uci_ctx, s, "hostapd_dir"); + } + } + return NULL; +} + +const char* uci_get_dawn_sort_order() { + struct uci_element *e; + uci_foreach_element(&uci_pkg->sections, e) { + struct uci_section *s = uci_to_section(e); + + if (strcmp(s->type, "ordering") == 0) + { + return uci_lookup_option_string(uci_ctx, s, "sort_order"); + } + } + return NULL; +} + +int uci_init() +{ + struct uci_context *ctx = uci_ctx; + + if (!ctx) { + ctx = uci_alloc_context(); + uci_ctx = ctx; + + ctx->flags &= ~UCI_FLAG_STRICT; + } else { + // shouldn't happen? + uci_pkg = uci_lookup_package(ctx, "dawn"); + if (uci_pkg) + uci_unload(ctx, uci_pkg); + } + + if (uci_load(ctx, "dawn", &uci_pkg)) + return -1; + + return 1; +} + +int uci_clear() +{ + if(uci_pkg != NULL) + { + uci_unload(uci_ctx, uci_pkg); + } + if(uci_ctx != NULL) + { + uci_free_context(uci_ctx); + } + return 1; } \ No newline at end of file diff --git a/src/utils/ubus.c b/src/utils/ubus.c index fdf73ae..734ed0c 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -8,16 +9,63 @@ #define ETH_ALEN 6 #endif +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 + #include "ubus.h" #include "networksocket.h" #include "utils.h" #include "dawn_uci.h" +#include "datastorage.h" -static struct ubus_context *ctx; +static struct ubus_context *ctx = NULL; static struct ubus_context *ctx_clients; /* own ubus conext otherwise strange behavior... */ + static struct ubus_subscriber hostapd_event; 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; + + + + +void update_clients(struct uloop_timeout *t); + +struct uloop_timeout client_timer = { + .cb = update_clients +}; +struct uloop_timeout hostapd_timer = { + .cb = update_hostapd_sockets +}; + +#define MAX_HOSTAPD_SOCKETS 10 +uint32_t 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, @@ -60,20 +108,24 @@ static const struct blobmsg_policy prob_policy[__PROB_MAX] = { 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_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}, }; enum { @@ -136,15 +188,86 @@ static int hostapd_notify(struct ubus_context *ctx, struct ubus_object *obj, static int add_subscriber(char *name); -static int subscribe_to_hostapd_interfaces(char *hostapd_dir); +static int subscribe_to_hostapd_interfaces(const char *hostapd_dir); static int ubus_get_clients(); -/* hostapd function */ -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +static int +add_mac(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg); -static void -blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const uint8_t *addr) { +static int get_hearing_map(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg); + +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); + +int hostapd_array_check_id(uint32_t id); + +void hostapd_array_insert(uint32_t id); + +void hostapd_array_delete(uint32_t id); + +static void ubus_add_oject(); + +static void respond_to_notify(uint32_t id); + +void add_client_update_timer(time_t time) { + uloop_timeout_set(&client_timer, time); +} + +int hostapd_array_check_id(uint32_t id) { + for (int i = 0; i <= hostapd_sock_last; i++) { + if (hostapd_sock_arr[i] == id) { + return 1; + } + } + return 0; +} + + +void hostapd_array_insert(uint32_t id) { + if (hostapd_sock_last < MAX_HOSTAPD_SOCKETS) { + hostapd_sock_last++; + hostapd_sock_arr[hostapd_sock_last] = id; + } + + for (int i = 0; i <= hostapd_sock_last; i++) { + printf("%d: %d\n", i, hostapd_sock_arr[i]); + } +} + +void hostapd_array_delete(uint32_t id) { + int i = 0; + int found_in_array = 0; + + if (hostapd_sock_last == -1) { + return; + } + + for (i = 0; i <= hostapd_sock_last; i++) { + if (hostapd_sock_arr[i] == id) { + found_in_array = 1; + break; + } + } + + for (int j = i; j <= hostapd_sock_last; j++) { + hostapd_sock_arr[j] = hostapd_sock_arr[j + 1]; + } + + if (hostapd_sock_last > -1 && found_in_array) { + hostapd_sock_last--; + } + +} + +void blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const uint8_t *addr) { char *s; s = blobmsg_alloc_string_buffer(buf, name, 20); @@ -152,26 +275,46 @@ blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const uint8_t *addr) blobmsg_add_string_buffer(buf); } -/* + static int decide_function(probe_entry *prob_req) { - // TODO: Refactor... - //printf("COUNTER: %d\n", prob_req->counter); + printf("COUNTER: %d\n", prob_req->counter); if (prob_req->counter < dawn_metric.min_probe_count) { return 0; } - if(better_ap_available(prob_req->bssid_addr, prob_req->client_addr)) + if(!dawn_metric.eval_probe_req) { + return 1; + } + + if (better_ap_available(prob_req->bssid_addr, prob_req->client_addr, 0)) { return 0; } return 1; } -*/ + + static void hostapd_handle_remove(struct ubus_context *ctx, struct ubus_subscriber *s, uint32_t id) { fprintf(stderr, "Object %08x went away\n", id); + ubus_unsubscribe(ctx, s, id); + hostapd_array_delete(id); +} + +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) { @@ -238,7 +381,7 @@ int parse_to_probe_req(struct blob_attr *msg, probe_entry *prob_req) { static int handle_auth_req(struct blob_attr *msg) { - print_array(); + print_probe_array(); auth_entry auth_req; parse_to_auth_req(msg, &auth_req); printf("AUTH Entry: "); @@ -249,22 +392,22 @@ static int handle_auth_req(struct blob_attr *msg) { printf("Entry found\n"); print_probe_entry(tmp); - /* - // block if entry was not already found in probe database - if(!(mac_is_equal(tmp.bssid_addr, auth_req.bssid_addr) && mac_is_equal(tmp.client_addr, auth_req.client_addr))) - { + if (!(mac_is_equal(tmp.bssid_addr, auth_req.bssid_addr) && mac_is_equal(tmp.client_addr, auth_req.client_addr))) { printf("DENY AUTH!\n"); - return UBUS_STATUS_UNKNOWN_ERROR; + return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; } if (!decide_function(&tmp)) { printf("DENY AUTH\n"); - return UBUS_STATUS_UNKNOWN_ERROR; - }*/ + return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + } + + // maybe add here if a client is already connected... + // delay problems... printf("ALLOW AUTH!\n"); - return 0; + return WLAN_STATUS_SUCCESS; } static int handle_assoc_req(struct blob_attr *msg) { @@ -277,46 +420,184 @@ static int handle_assoc_req(struct blob_attr *msg) { static int handle_probe_req(struct blob_attr *msg) { //printf("[WC] Parse Probe Request\n"); probe_entry prob_req; - parse_to_probe_req(msg, &prob_req); - //insert_to_list(prob_req, 1); - //probe_entry tmp_probe = - insert_to_array(prob_req, 1); + probe_entry tmp_prob_req; + if(parse_to_probe_req(msg, &prob_req) == 0) + { + tmp_prob_req = insert_to_array(prob_req, 1); + //print_probe_array(); + send_blob_attr_via_network(msg, "probe"); + } - - // send probe via network - char *str; - str = blobmsg_format_json(msg, true); - send_string_enc(str); - - printf("[WC] Hostapd-Probe: %s : %s\n", "probe", str); - - print_array(); - /* - // deny access - if (!decide_function(&tmp_probe)) { + if (!decide_function(&tmp_prob_req)) { //printf("MAC WILL BE DECLINED!!!\n"); - return UBUS_STATUS_UNKNOWN_ERROR; - }*/ + return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + } //printf("MAC WILL BE ACCEPDTED!!!\n"); + return WLAN_STATUS_SUCCESS; +} + +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) +{ + //printf("HANDLING NETWORK MSG: %s\n", 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_get_string(tb[NETWORK_METHOD]); + //data = blobmsg_get_string(tb[NETWORK_DATA]); + + method = blobmsg_data(tb[NETWORK_METHOD]); + data = blobmsg_data(tb[NETWORK_DATA]); + + blob_buf_init(&data_buf, 0); + blobmsg_add_json_from_string(&data_buf, data); + + + //printf("DO STRINGCOMPARE: %s : %s!\n", method, data); + if(!data_buf.head) + { + //printf("NULL?!\n"); + return -1; + } + + if(blob_len(data_buf.head) <= 0) + { + //printf("NULL?!\n"); + return -1; + } + + if(strlen(method) < 5) + { + //printf("STRING IS LESS THAN 5!\n"); + return -1; + } + + if (strncmp(method, "probe", 5) == 0) { + //printf("METHOD PROBE\n"); + probe_entry entry; + if(parse_to_probe_req(data_buf.head, &entry) == 0) + { + insert_to_array(entry, 0); + //print_probe_array(); + } + } else if (strncmp(method, "clients", 5) == 0) { + //printf("METHOD CLIENTS\n"); + //printf("PARSING CLIENTS NETWORK MSG!\n"); + 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); + } + + + /* + hostapd_notify_entry entry; + parse_to_hostapd_notify(data_buf.head, &entry); + + client client_entry; + memcpy(client_entry.bssid_addr, client_entry.bssid_addr, sizeof(uint8_t) * ETH_ALEN ); + memcpy(client_entry.client_addr, client_entry.client_addr, sizeof(uint8_t) * ETH_ALEN ); + + pthread_mutex_lock(&client_array_mutex); + client_array_delete(client_entry); + pthread_mutex_unlock(&client_array_mutex);*/ + //} + //free(method); + //free(data); + //printf("HANDLING FINISHED NETWORK MSG!\n"); + return 0; +} + + +int send_blob_attr_via_network(struct blob_attr *msg, char* method) +{ + if(!msg) + { + return -1; + } + + char *data_str; + char *str; + data_str = blobmsg_format_json(msg, true); + blob_buf_init(&b_send_network, 0); + blobmsg_add_string(&b_send_network, "method", method); + blobmsg_add_string(&b_send_network, "data", data_str); + + + //blobmsg_add_blob(&b, msg); + str = blobmsg_format_json(b_send_network.head, true); + send_string_enc(str); + //free(str); + //free(data_str); return 0; } static int hostapd_notify(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { - printf("METHOD new: %s\n",method); + char *str; + str = blobmsg_format_json(msg, true); + printf("METHOD new: %s : %s\n", method, str); + + //TODO CHECK IF FREE IS CORREECT! + free(str); // TODO: Only handle probe request and NOT assoc, ... if (strncmp(method, "probe", 5) == 0) { return handle_probe_req(msg); - } - else if (strncmp(method, "auth", 4) == 0) { + } else if (strncmp(method, "auth", 4) == 0) { return handle_auth_req(msg); - } - else if (strncmp(method, "assoc", 5) == 0) { + } else if (strncmp(method, "assoc", 5) == 0) { return handle_assoc_req(msg); + } else if (strncmp(method, "deauth", 6) == 0) { + send_blob_attr_via_network(msg, "deauth"); + return handle_deauth_req(msg); } return 0; } @@ -329,25 +610,26 @@ static int add_subscriber(char *name) { return -1; } - // add callbacks - hostapd_event.remove_cb = hostapd_handle_remove; - hostapd_event.cb = hostapd_notify; + if (hostapd_array_check_id(id)) { + return 0; + } int ret = ubus_subscribe(ctx, &hostapd_event, id); - + hostapd_array_insert(id); fprintf(stderr, "Watching object %08x: %s\n", id, ubus_strerror(ret)); + // respond to notify... + respond_to_notify(id); + return 0; } -static int subscribe_to_hostapd_interfaces(char *hostapd_dir) { +static int subscribe_to_hostapd_interfaces(const char *hostapd_dir) { DIR *dirp; struct dirent *entry; - int ret = ubus_register_subscriber(ctx, &hostapd_event); - if (ret) { - fprintf(stderr, "Failed to add watch handler: %s\n", ubus_strerror(ret)); - return -1; + if (ctx == NULL) { + return 0; } dirp = opendir(hostapd_dir); // error handling? @@ -359,16 +641,38 @@ static int subscribe_to_hostapd_interfaces(char *hostapd_dir) { if (entry->d_type == DT_SOCK) { char subscribe_name[256]; sprintf(subscribe_name, "hostapd.%s", entry->d_name); - printf("Subscribing to %s\n", subscribe_name); add_subscriber(subscribe_name); } } closedir(dirp); + return 0; +} + +static int subscribe_to_hostapd(const char *hostapd_dir) { + + if (ctx == NULL) { + return 0; + } + + printf("Registering ubus event subscriber!\n"); + int ret = ubus_register_subscriber(ctx, &hostapd_event); + if (ret) { + fprintf(stderr, "Failed to add watch handler: %s\n", ubus_strerror(ret)); + return -1; + } + + // add callbacks + hostapd_event.remove_cb = hostapd_handle_remove; + hostapd_event.cb = hostapd_notify; + + subscribe_to_hostapd_interfaces(hostapd_dir); + + // free(hostapd_dir); // free string return 0; } -int dawn_init_ubus(const char *ubus_socket, char *hostapd_dir) { +int dawn_init_ubus(const char *ubus_socket, const char *hostapd_dir) { uloop_init(); signal(SIGPIPE, SIG_IGN); @@ -385,12 +689,27 @@ int dawn_init_ubus(const char *ubus_socket, char *hostapd_dir) { // set dawn metric dawn_metric = uci_get_dawn_metric(); - subscribe_to_hostapd_interfaces(hostapd_dir); + subscribe_to_hostapd(hostapd_dir); + + // update hostapd + uloop_timeout_add(&hostapd_timer); + + // remove probe + uloop_add_data_cbs(); + + // get clients + const char *ubus_socket_clients = NULL; + ctx_clients = ubus_connect(ubus_socket_clients); + uloop_timeout_add(&client_timer); + //ubus_call_umdns(); + ubus_add_oject(); + uloop_run(); + close_socket(); ubus_free(ctx); @@ -462,7 +781,7 @@ dump_client_table(struct blob_attr *head, int len, const char *bssid_addr, uint3 int tmp_int_mac[ETH_ALEN]; uint8_t tmp_mac[ETH_ALEN]; - sscanf((char *) hdr->name, "%x:%x:%x:%x:%x:%x", STR2MAC(tmp_int_mac)); + 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]; @@ -473,7 +792,20 @@ dump_client_table(struct blob_attr *head, int len, const char *bssid_addr, uint3 int parse_to_clients(struct blob_attr *msg, int do_kick, uint32_t id) { struct blob_attr *tb[__CLIENT_TABLE_MAX]; - //printf("[CLIENTS] : Parse Clients\n"); + 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)); @@ -488,6 +820,14 @@ int parse_to_clients(struct blob_attr *msg, int do_kick, uint32_t id) { ap_entry.ht = blobmsg_get_u8(tb[CLIENT_TABLE_HT]); ap_entry.vht = blobmsg_get_u8(tb[CLIENT_TABLE_VHT]); ap_entry.channel_utilization = blobmsg_get_u32(tb[CLIENT_TABLE_CHAN_UTIL]); + strcpy((char*)ap_entry.ssid, blobmsg_get_string(tb[CLIENT_TABLE_SSID])); + + if (tb[CLIENT_TABLE_NUM_STA]) { + ap_entry.station_count = blobmsg_get_u32(tb[CLIENT_TABLE_NUM_STA]); + } else { + ap_entry.station_count = 0; + } + insert_to_ap_array(ap_entry); if (do_kick) { @@ -502,52 +842,25 @@ static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_ if (!msg) return; + send_blob_attr_via_network(msg, "clients"); parse_to_clients(msg, 1, req->peer); - char *str = blobmsg_format_json(msg, true); - send_string_enc(str); print_client_array(); print_ap_array(); } static int ubus_get_clients() { - DIR *dirp; - struct dirent *entry; - - dirp = opendir(hostapd_dir_glob); // error handling? - if (!dirp) { - fprintf(stderr, "No hostapd sockets!\n"); - return -1; + for (int i = 0; i <= hostapd_sock_last; i++) { + int timeout = 1; + ubus_invoke(ctx_clients, hostapd_sock_arr[i], "get_clients", NULL, ubus_get_clients_cb, NULL, timeout * 1000); } - while ((entry = readdir(dirp)) != NULL) { - if (entry->d_type == DT_SOCK) { - char hostapd_iface[256]; - uint32_t id; - sprintf(hostapd_iface, "hostapd.%s", entry->d_name); - int ret = ubus_lookup_id(ctx_clients, hostapd_iface, &id); - if (!ret) { - int timeout = 1; - ubus_invoke(ctx_clients, id, "get_clients", NULL, ubus_get_clients_cb, NULL, timeout * 1000); - } - } - } - closedir(dirp); return 0; } -void *update_clients_thread(void *arg) { - time_t time_update_client = *(time_t*)arg; - printf("Update client thread with time: %lu\n", time_update_client); - - const char *ubus_socket = NULL; - ctx_clients = ubus_connect(ubus_socket); - - while (1) { - sleep(time_update_client); - printf("[Thread] : Kicking clients!\n"); - ubus_get_clients(); - } - return 0; +void update_clients(struct uloop_timeout *t) { + ubus_get_clients(); + // maybe to much?! don't set timer again... + uloop_timeout_set(&client_timer, timeout_config.update_client * 1000); } void *update_connections_thread(void *arg) { @@ -559,29 +872,11 @@ void *update_connections_thread(void *arg) { return 0; } -void *kick_clients_thread(void *arg) { - while (1) { - sleep(TIME_THRESHOLD_CLIENT_KICK); - printf("[Thread] : Updating clients!\n"); - // a4:2b:b0:de:f1:fd - // a4:2b:b0:de:f1:fe -/* - int tmp_int_mac[ETH_ALEN]; - uint8_t tmp_mac[ETH_ALEN]; - sscanf("a4:2b:b0:de:f1:fd", "%x:%x:%x:%x:%x:%x", STR2MAC(tmp_int_mac)); - for(int i = 0; i < ETH_ALEN; ++i ) - tmp_mac[i] = (uint8_t) tmp_int_mac[i]; - //kick_clients(tmp_mac); - - sscanf("a4:2b:b0:de:f1:fe", "%x:%x:%x:%x:%x:%x", STR2MAC(tmp_int_mac)); - for(int i = 0; i < ETH_ALEN; ++i ) - tmp_mac[i] = (uint8_t) tmp_int_mac[i];*/ - //kick_clients(tmp_mac); - } - return 0; +void update_hostapd_sockets(struct uloop_timeout *t) { + subscribe_to_hostapd_interfaces(hostapd_dir_glob); + uloop_timeout_set(&hostapd_timer, timeout_config.update_hostapd * 1000); } - void del_client_all_interfaces(const uint8_t *client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time) { /* Problem: On which interface is the client? @@ -598,26 +893,10 @@ void del_client_all_interfaces(const uint8_t *client_addr, uint32_t reason, uint blobmsg_add_u8(&b, "deauth", deauth); blobmsg_add_u32(&b, "ban_time", ban_time); - DIR *dirp; - struct dirent *entry; - dirp = opendir(hostapd_dir_glob); // error handling? - if (!dirp) { - fprintf(stderr, "No hostapd sockets!\n"); - return; + for (int i = 0; i <= hostapd_sock_last; i++) { + int timeout = 1; + ubus_invoke(ctx_clients, hostapd_sock_arr[i], "del_client", b.head, NULL, NULL, timeout * 1000); } - while ((entry = readdir(dirp)) != NULL) { - if (entry->d_type == DT_SOCK) { - char hostapd_iface[256]; - uint32_t id; - sprintf(hostapd_iface, "hostapd.%s", entry->d_name); - int ret = ubus_lookup_id(ctx_clients, hostapd_iface, &id); - if (!ret) { - int timeout = 1; - ubus_invoke(ctx_clients, id, "del_client", b.head, NULL, NULL, timeout * 1000); - } - } - } - closedir(dirp); } void del_client_interface(uint32_t id, const uint8_t *client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time) { @@ -676,9 +955,7 @@ static void ubus_umdns_cb(struct ubus_request *req, int type, struct blob_attr * print_tcp_array(); } - -int ubus_call_umdns() -{ +int ubus_call_umdns() { u_int32_t id; if (ubus_lookup_id(ctx, "umdns", &id)) { fprintf(stderr, "Failed to look up test object for %s\n", "umdns"); @@ -690,4 +967,130 @@ int ubus_call_umdns() ubus_invoke(ctx_clients, id, "browse", NULL, ubus_umdns_cb, NULL, timeout * 1000); return 0; +} + +int ubus_send_probe_via_network(struct probe_entry_s probe_entry) { + + printf("SENDING PROBE VIA NETWORK!\n"); + + blob_buf_init(&b_probe, 0); + blobmsg_add_macaddr(&b_probe, "bssid", probe_entry.bssid_addr); + blobmsg_add_macaddr(&b_probe, "address", probe_entry.client_addr); + blobmsg_add_macaddr(&b_probe, "target", probe_entry.target_addr); + blobmsg_add_u32(&b_probe, "signal", probe_entry.signal); + blobmsg_add_u32(&b_probe, "freq", probe_entry.freq); + blobmsg_add_u8(&b_probe, "ht_support", probe_entry.ht_support); + blobmsg_add_u8(&b_probe, "vht_support", probe_entry.vht_support); + + send_blob_attr_via_network(b_probe.head, "probe"); + + return 0; +} + +int send_set_probe(uint8_t client_addr[]) +{ + + printf("SENDING SET PROBE VIA NETWORK!\n"); + + blob_buf_init(&b_probe, 0); + blobmsg_add_macaddr(&b_probe, "bssid", client_addr); + blobmsg_add_macaddr(&b_probe, "address", client_addr); + + send_blob_attr_via_network(b_probe.head, "setprobe"); + + return 0; +} + +enum { + MAC_ADDR, + __ADD_DEL_MAC_MAX +}; + +static const struct blobmsg_policy add_del_policy[__ADD_DEL_MAC_MAX] = { + [MAC_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, +}; + +static const struct ubus_method dawn_methods[] = { + UBUS_METHOD("add_mac", add_mac, add_del_policy), + UBUS_METHOD_NOARG("get_hearing_map", get_hearing_map), + UBUS_METHOD_NOARG("get_network", get_network) + //UBUS_METHOD_NOARG("get_aps"); + //UBUS_METHOD_NOARG("get_clients"); +}; + +static struct ubus_object_type dawn_object_type = + UBUS_OBJECT_TYPE("dawn", dawn_methods); + +static struct ubus_object dawn_object = { + .name = "dawn", + .type = &dawn_object_type, + .methods = dawn_methods, + .n_methods = ARRAY_SIZE(dawn_methods), +}; + +static int add_mac(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) { + + struct blob_attr *tb[__ADD_DEL_MAC_MAX]; + uint8_t addr[ETH_ALEN]; + + blobmsg_parse(add_del_policy, __ADD_DEL_MAC_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[MAC_ADDR]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (hwaddr_aton(blobmsg_data(tb[MAC_ADDR]), addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + if(insert_to_maclist(addr) == 0) + { + write_mac_to_file("/etc/dawn/mac_list", addr); + } + + return 0; +} + +static int get_hearing_map(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) { + + build_hearing_map_sort_client(&b); + ubus_send_reply(ctx, req, b.head); + return 0; +} + + +static int get_network(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) { + + build_network_overview(&b); + ubus_send_reply(ctx, req, b.head); + return 0; +} + +static void ubus_add_oject() +{ + int ret; + + ret = ubus_add_object(ctx, &dawn_object); + if (ret) + fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret)); + printf("ADDED UBUS OBJECT!!!\n"); + + /*ret = ubus_register_subscriber(ctx, &test_event); + if (ret) + fprintf(stderr, "Failed to add watch handler: %s\n", ubus_strerror(ret)); + */ +} + + +static void respond_to_notify(uint32_t id) { + printf("SENDING NOTIFY!!!\n"); + blob_buf_init(&b, 0); + blobmsg_add_u32(&b, "notify_response", 1); + + int timeout = 1; + ubus_invoke(ctx, id, "notify_response", b.head, NULL, NULL, timeout * 1000); } \ No newline at end of file diff --git a/src/utils/utils.c b/src/utils/utils.c index f200114..f49403e 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -1,6 +1,24 @@ #include "utils.h" #include "ubus.h" +int string_is_greater(uint8_t* str, uint8_t* str_2) { + + int length_1 = strlen((char*)str); + int length_2 = strlen((char*)str_2); + + int length = length_1 < length_2 ? length_1 : length_2; + + for (int i = 0; i < length; i++) { + if (str[i] > str_2[i]) { + return 1; + } + if (str[i] < str_2[i]) { + return 0; + } + } + return length_1 > length_2; +} + int hex_to_bin(char ch) { if ((ch >= '0') && (ch <= '9')) return ch - '0'; ch = tolower(ch); @@ -23,4 +41,40 @@ int hwaddr_aton(const char *txt, uint8_t *addr) { } return 0; +} + +int convert_mac(char *in, char *out) { + int i, j = 0; + + for (i = 0; i < 6; i++) { + if (in[j + 1] != ':' && in[j + 1] != '\0') { + out[3 * i] = toupper(in[j]); + out[(3 * i) + 1] = toupper(in[j + 1]); + out[(3 * i) + 2] = in[j + 2]; + j += 3; + } else { + out[3 * i] = '0'; + out[(3 * i) + 1] = toupper(in[j]); + out[(3 * i) + 2] = toupper(in[j + 1]); + j += 2; + } + } + return 0; +} + +void write_mac_to_file(char* path, uint8_t addr[]) +{ + FILE *f = fopen(path, "a"); + if (f == NULL) + { + printf("Error opening file!\n"); + exit(1); + } + + char mac_buf[20]; + sprintf(mac_buf, MACSTR, MAC2STR(addr)); + + fprintf(f, "%s\n", mac_buf); + + fclose(f); } \ No newline at end of file