diff --git a/files/dawn.config b/files/dawn.config index 817255c..4009ec7 100644 --- a/files/dawn.config +++ b/files/dawn.config @@ -1,36 +1,38 @@ -config settings network - option broadcast_ip '225.0.0.37' - option broadcast_port '1025' - option multicast '1' - option shared_key 'Niiiiiiiiiiiiiik' - option iv 'Niiiiiiiiiiiiiik' +config network + option broadcast_ip '225.0.0.37' + option broadcast_port '1025' + option multicast '1' + option shared_key 'Niiiiiiiiiiiiiik' + option iv 'Niiiiiiiiiiiiiik' -config settings ordering +config ordering option sort_order 'csfb' -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' - option remove_ap '460' - option update_hostapd '10' +config times + option update_client '10' + option remove_client '120' + 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 low_rssi '-500' - option freq '100' - option chan_util '50' - option max_chan_util '-50' - option rssi_val '-60' - option low_rssi_val '-80' - option chan_util_val '140' - option max_chan_util_val '170' - option min_probe_count '2' - option bandwith_threshold '6' +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 '0' + 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' \ No newline at end of file diff --git a/files/dawn.init b/files/dawn.init index 8e9a39c..8e83253 100755 --- a/files/dawn.init +++ b/files/dawn.init @@ -11,51 +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 - - config_get multicast network multicast - 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}" - - if [ "${multicast}" -gt 0 ]; then - procd_append_param command -m - fi - + 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 index e69de29..8a35cbc 100644 --- a/files/mac_list +++ b/files/mac_list @@ -0,0 +1,2 @@ +a4:2b:b0:de:f1:fd +f0:79:60:1c:26:f0 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 00c0832..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); diff --git a/src/include/crypto.h b/src/include/crypto.h index 8124b2d..fd80314 100644 --- a/src/include/crypto.h +++ b/src/include/crypto.h @@ -9,7 +9,7 @@ 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); diff --git a/src/include/datastorage.h b/src/include/datastorage.h index 428782d..8d1267e 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -8,14 +8,30 @@ #include #include #include +#include + #ifndef ETH_ALEN #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; @@ -33,6 +49,8 @@ struct probe_metric_s { int max_chan_util_val; int min_probe_count; int bandwith_threshold; + int use_station_count; + int eval_probe_req; }; struct time_config_s { @@ -43,6 +61,15 @@ struct time_config_s { time_t update_hostapd; }; +struct network_config_s { + const char* broadcast_ip; + int broadcast_port; + const char* multicast; + const char* shared_key; + const char* iv; + int bool_multicast; +}; + struct time_config_s timeout_config; // ---------------- Global variables ---------------- @@ -133,6 +160,7 @@ typedef struct ap_s { uint8_t vht; uint32_t channel_utilization; time_t time; + uint32_t station_count; } ap; // ---------------- Defines ---------------- @@ -168,6 +196,10 @@ void print_ap_array(); ap ap_array_get_ap(uint8_t bssid_addr[]); +int build_hearing_map_sort_client(struct blob_buf *b); + +int build_network_overview(struct blob_buf *b); + /* Utils */ // ---------------- Defines ------------------- @@ -175,14 +207,14 @@ ap ap_array_get_ap(uint8_t bssid_addr[]); #define TIME_THRESHOLD 120 // every minute // ---------------- Global variables ---------------- -char sort_string[SORT_NUM]; +char* sort_string; // ---------------- Functions ------------------- int mac_is_equal(uint8_t addr1[], uint8_t addr2[]); int mac_is_greater(uint8_t addr1[], uint8_t addr2[]); -int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]); +int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], int automatic_kick); /* List stuff */ 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/networksocket.h b/src/include/networksocket.h index 4e11724..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 _multicast_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 1fdb59d..b06c916 100644 --- a/src/include/ubus.h +++ b/src/include/ubus.h @@ -6,9 +6,7 @@ #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); @@ -26,7 +24,7 @@ void del_client_all_interfaces(const uint8_t *client_addr, uint32_t reason, uint void *update_clients_thread(void *arg); -char *hostapd_dir_glob; +const char *hostapd_dir_glob; int ubus_call_umdns(); @@ -40,4 +38,6 @@ 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); + #endif diff --git a/src/include/utils.h b/src/include/utils.h index ec0e87a..e07a776 100644 --- a/src/include/utils.h +++ b/src/include/utils.h @@ -15,4 +15,6 @@ 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[]); + #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index bc24151..4252b4f 100644 --- a/src/main.c +++ b/src/main.c @@ -10,18 +10,19 @@ #include "dawn_uci.h" #include "crypto.h" -#define BUFSIZE 17 -#define BUFSIZE_DIR 256 - void daemon_shutdown(); void signal_handler(int sig); -struct sigaction newSigAction; +int init_mutex(); + +struct sigaction signal_action; void daemon_shutdown() { + // kill threads close_socket(); + uci_clear(); printf("Cancelling Threads!\n"); uloop_cancelled = true; @@ -34,92 +35,24 @@ void daemon_shutdown() { } void signal_handler(int sig) { - printf("SOME SIGNAL RECEIVED!\n"); switch (sig) { case SIGHUP: + daemon_shutdown(); break; case SIGINT: + daemon_shutdown(); + break; case SIGTERM: daemon_shutdown(); exit(EXIT_SUCCESS); - break; default: + daemon_shutdown(); break; } } -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]; - int multicast = 0; - - while ((ch = getopt(argc, argv, "cs:p:i:b:o:h:i:k:v:m")) != -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; - case 'm': - multicast = 1; - break; - default: - break; - } - } - - 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(); - timeout_config = time_config; // TODO: Refactor... - +int init_mutex() +{ if (pthread_mutex_init(&list_mutex, NULL) != 0) { printf("\n mutex init failed\n"); return 1; @@ -139,10 +72,43 @@ int main(int argc, char **argv) { printf("\n mutex init failed\n"); return 1; } + return 0; +} - init_socket_runopts(opt_broadcast_ip, opt_broadcast_port, multicast); +int main(int argc, char **argv) { - dawn_init_ubus(ubus_socket, opt_hostapd_dir); + const char *ubus_socket = NULL; + + 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... + + hostapd_dir_glob = uci_get_dawn_hostapd_dir(); + sort_string = (char*) uci_get_dawn_sort_order(); + + init_mutex(); + + init_socket_runopts(net_config.broadcast_ip, net_config.broadcast_port, net_config.bool_multicast); + + 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 b002046..7d6fc94 100644 --- a/src/network/broadcastsocket.c +++ b/src/network/broadcastsocket.c @@ -33,7 +33,7 @@ int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_ addr->sin_port = htons(_broadcast_port); while (bind(sock, (struct sockaddr *) addr, sizeof(*addr)) < - 0) { + 0) { fprintf(stderr, "Binding socket failed!\n"); sleep(1); } diff --git a/src/network/multicastsocket.c b/src/network/multicastsocket.c index b67499e..66664f2 100644 --- a/src/network/multicastsocket.c +++ b/src/network/multicastsocket.c @@ -69,13 +69,12 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_ 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"); +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; diff --git a/src/network/networksocket.c b/src/network/networksocket.c index 3f0a003..2e29d33 100644 --- a/src/network/networksocket.c +++ b/src/network/networksocket.c @@ -35,9 +35,9 @@ void *receive_msg(void *args); void *receive_msg_enc(void *args); -int init_socket_runopts(char *_ip, char *_port, int _multicast_socket) { +int init_socket_runopts(const char *_ip, int _port, int _multicast_socket) { - port = atoi(_port); + port = _port; ip = _ip; multicast_socket = _multicast_socket; @@ -216,7 +216,7 @@ int send_string_enc(char *msg) { } void close_socket() { - if(multicast_socket){ + if (multicast_socket) { remove_multicast_socket(sock); } close(sock); diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index 4126702..dfc36b8 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -41,9 +41,14 @@ int probe_array_update_rssi(uint8_t bssid_addr[], uint8_t client_addr[], uint32_ 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, int automatic_kick); + int probe_entry_last = -1; int client_entry_last = -1; int ap_entry_last = -1; +int mac_list_entry_last = -1; void remove_probe_array_cb(struct uloop_timeout *t); @@ -63,6 +68,85 @@ struct uloop_timeout ap_timeout = { .cb = remove_ap_array_cb }; +int build_hearing_map_sort_client(struct blob_buf *b) +{ + pthread_mutex_lock(&probe_array_mutex); + + void *client_list, *ap_list; + char ap_mac_buf[20]; + char client_mac_buf[20]; + + blob_buf_init(b, 0); + int i; + for (i = 0; i <= probe_entry_last; i++) { + 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; i <= probe_entry_last; k++){ + if(!mac_is_equal(probe_array[k].client_addr, probe_array[i].client_addr)) + { + i = k - 1; + break; + } + 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); + + ap ap_entry = ap_array_get_ap(probe_array[k].bssid_addr); + + // check if ap entry is available + if (mac_is_equal(ap_entry.bssid_addr, probe_array[k].bssid_addr)) { + 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); + } + pthread_mutex_unlock(&probe_array_mutex); + return 0; +} + +int build_network_overview(struct blob_buf *b) +{ + pthread_mutex_lock(&probe_array_mutex); + + void *client_list, *ap_list; + char ap_mac_buf[20]; + char client_mac_buf[20]; + + blob_buf_init(b, 0); + int i; + for (i = 0; i <= client_entry_last; i++) { + int k; + sprintf(ap_mac_buf, MACSTR, MAC2STR(client_array[i].bssid_addr)); + ap_list = blobmsg_open_table(b, ap_mac_buf); + for (k = i; i <= client_entry_last; k++){ + if(!mac_is_equal(client_array[k].bssid_addr, client_array[i].bssid_addr)) + { + i = k - 1; + break; + } + 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); + } + pthread_mutex_unlock(&probe_array_mutex); + return 0; +} + int eval_probe_metric(struct probe_entry_s probe_entry) { int score = 0; @@ -89,7 +173,28 @@ int eval_probe_metric(struct probe_entry_s probe_entry) { return score; } -int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]) { +int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare, 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); + if (automatic_kick) { + return (ap_entry_own.station_count - 1) > ap_entry_to_compre.station_count; + } else { + return ap_entry_own.station_count > ap_entry_to_compre.station_count; + } + } + + 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 @@ -110,6 +215,7 @@ 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; } @@ -122,26 +228,45 @@ int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]) { 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; + } + + 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) { + // if ap have same value but station count is different... + if (compare_station_count(bssid_addr, probe_array[k].bssid_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; @@ -171,19 +296,20 @@ void kick_clients(uint8_t bssid[], uint32_t id) { } + int do_kick = kick_client(client_array[j]); + // better ap available - if (kick_client(client_array[j]) > 0) { + 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)) - { + 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){ + if (rx_rate > dawn_metric.bandwith_threshold) { printf("Client is probably in active transmisison. Don't kick! RxRate is: %f\n", rx_rate); continue; } @@ -199,7 +325,7 @@ void kick_clients(uint8_t bssid[], uint32_t id) { break; // no entry in probe array for own bssid - } else if (kick_client(client_array[j]) == -1) { + } 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); @@ -211,6 +337,8 @@ void kick_clients(uint8_t bssid[], uint32_t id) { } } + printf("---------------------------\n"); + pthread_mutex_unlock(&probe_array_mutex); pthread_mutex_unlock(&client_array_mutex); } @@ -239,35 +367,15 @@ int client_array_go_next_help(char sort_order[], int i, client 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, @@ -479,9 +587,6 @@ 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, MACSTR, MAC2STR(bssid_addr)); - if (ap_entry_last == -1) { return ret; } @@ -578,8 +683,7 @@ void remove_old_ap_entries(time_t current_time, long long int threshold) { } } -void uloop_add_data_cbs() -{ +void uloop_add_data_cbs() { uloop_timeout_add(&probe_timeout); uloop_timeout_add(&client_timeout); uloop_timeout_add(&ap_timeout); @@ -593,8 +697,7 @@ void remove_probe_array_cb(struct uloop_timeout *t) { uloop_timeout_set(&probe_timeout, timeout_config.remove_probe * 1000); } -void remove_client_array_cb(struct uloop_timeout *t) -{ +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); @@ -620,6 +723,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[]); diff --git a/src/utils/dawn_iwinfo.c b/src/utils/dawn_iwinfo.c index 7cacad6..7984f31 100644 --- a/src/utils/dawn_iwinfo.c +++ b/src/utils/dawn_iwinfo.c @@ -17,7 +17,7 @@ int get_rssi(const char *ifname, uint8_t *client_addr); int get_bandwith(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate); -#define IWINFO_BUFSIZE 24 * 1024 +#define IWINFO_BUFSIZE 24 * 1024 int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate) { @@ -33,8 +33,7 @@ int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate) while ((entry = readdir(dirp)) != NULL) { if (entry->d_type == DT_SOCK) { - if(get_bandwith(entry->d_name, client_addr, rx_rate, tx_rate)) - { + if (get_bandwith(entry->d_name, client_addr, rx_rate, tx_rate)) { sucess = 1; break; } @@ -44,7 +43,7 @@ int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate) return sucess; } -int get_bandwith(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate){ +int get_bandwith(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate) { int i, len; char buf[IWINFO_BUFSIZE]; @@ -53,23 +52,18 @@ int get_bandwith(const char *ifname, uint8_t *client_addr, float *rx_rate, float iw = iwinfo_backend(ifname); - if (iw->assoclist(ifname, buf, &len)) - { + if (iw->assoclist(ifname, buf, &len)) { printf("No information available\n"); return 0; - } - else if (len <= 0) - { + } else if (len <= 0) { printf("No station connected\n"); return 0; } - for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) - { + 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)) - { + 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; @@ -99,7 +93,7 @@ int get_rssi_iwinfo(__uint8_t *client_addr) { while ((entry = readdir(dirp)) != NULL) { if (entry->d_type == DT_SOCK) { rssi = get_rssi(entry->d_name, client_addr); - if(rssi != INT_MIN) + if (rssi != INT_MIN) break; } } @@ -107,7 +101,7 @@ int get_rssi_iwinfo(__uint8_t *client_addr) { return rssi; } -int get_rssi(const char *ifname, uint8_t *client_addr){ +int get_rssi(const char *ifname, uint8_t *client_addr) { int i, len; char buf[IWINFO_BUFSIZE]; @@ -116,23 +110,19 @@ int get_rssi(const char *ifname, uint8_t *client_addr){ iw = iwinfo_backend(ifname); - if (iw->assoclist(ifname, buf, &len)) - { + if (iw->assoclist(ifname, buf, &len)) { printf("No information available\n"); return INT_MIN; - } - else if (len <= 0) - { + } else if (len <= 0) { printf("No station connected\n"); return INT_MIN; } - for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) - { + 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; + if (mac_is_equal(client_addr, e->mac)) + return e->signal; } return INT_MIN; diff --git a/src/utils/dawn_uci.c b/src/utils/dawn_uci.c index 9ca9938..71cdde3 100644 --- a/src/utils/dawn_uci.c +++ b/src/utils/dawn_uci.c @@ -4,76 +4,38 @@ #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' - */ +// 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); - - char tmp_update_hostapd[] = "dawn.times.update_hostapd"; - if (uci_lookup_ptr(c, &ptr, tmp_update_hostapd, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if (ptr.o->type == UCI_TYPE_STRING) - ret.update_hostapd = atoi(ptr.o->v.string); - - char tmp_remove_ap[] = "dawn.times.remove_ap"; - if (uci_lookup_ptr(c, &ptr, tmp_remove_ap, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if (ptr.o->type == UCI_TYPE_STRING) - ret.remove_ap = atoi(ptr.o->v.string); - - printf("Times: %lu, %lu, %lu %lu\n", ret.update_client, ret.remove_client, ret.remove_probe, ret.update_hostapd); - - uci_free_context(c); return ret; } @@ -81,137 +43,116 @@ struct time_config_s uci_get_time_config() { 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_rssi_val[] = "dawn.metric.rssi_val"; - if (uci_lookup_ptr(c, &ptr, tmp_rssi_val, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if (ptr.o->type == UCI_TYPE_STRING) - ret.rssi_val = 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); - - char tmp_chan_util_val[] = "dawn.metric.chan_util_val"; - if (uci_lookup_ptr(c, &ptr, tmp_chan_util_val, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if (ptr.o->type == UCI_TYPE_STRING) - ret.chan_util_val = atoi(ptr.o->v.string); - - - char tmp_max_chan_util_val[] = "dawn.metric.max_chan_util_val"; - if (uci_lookup_ptr(c, &ptr, tmp_max_chan_util_val, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if (ptr.o->type == UCI_TYPE_STRING) - ret.max_chan_util_val = 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); - - char tmp_low_rssi[] = "dawn.metric.low_rssi"; - if (uci_lookup_ptr(c, &ptr, tmp_low_rssi, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if (ptr.o->type == UCI_TYPE_STRING) - ret.low_rssi = atoi(ptr.o->v.string); - - char tmp_low_rssi_val[] = "dawn.metric.low_rssi_val"; - if (uci_lookup_ptr(c, &ptr, tmp_low_rssi_val, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if (ptr.o->type == UCI_TYPE_STRING) - ret.low_rssi_val = atoi(ptr.o->v.string); - - char tmp_bandwith_threshold[] = "dawn.metric.bandwith_threshold"; - if (uci_lookup_ptr(c, &ptr, tmp_bandwith_threshold, 1) != UCI_OK) { - uci_perror(c, "uci_get_daw_metric Error"); - return ret; - } - if (ptr.o->type == UCI_TYPE_STRING) - ret.bandwith_threshold = 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 281fa08..6151a53 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -109,6 +109,7 @@ enum { CLIENT_TABLE_HT, CLIENT_TABLE_VHT, CLIENT_TABLE_CHAN_UTIL, + CLIENT_TABLE_NUM_STA, __CLIENT_TABLE_MAX, }; @@ -119,6 +120,7 @@ static const struct blobmsg_policy client_table_policy[__CLIENT_TABLE_MAX] = { [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 { @@ -160,25 +162,37 @@ 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(); -int hostapd_array_check_id(uint32_t id); -void hostapd_array_insert(uint32_t id); -void hostapd_array_delete(uint32_t id); +static int +add_mac(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg); -void add_client_update_timer(time_t time) -{ +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); + +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(); + +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) - { +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; } } @@ -186,21 +200,18 @@ int hostapd_array_check_id(uint32_t id) } -void hostapd_array_insert(uint32_t id) -{ - if(hostapd_sock_last < MAX_HOSTAPD_SOCKETS) { +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]); + 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) -{ +void hostapd_array_delete(uint32_t id) { int i = 0; int found_in_array = 0; @@ -208,9 +219,8 @@ void hostapd_array_delete(uint32_t id) return; } - for(i = 0; i <= hostapd_sock_last; i++) - { - if(hostapd_sock_arr[i] == id) { + for (i = 0; i <= hostapd_sock_last; i++) { + if (hostapd_sock_arr[i] == id) { found_in_array = 1; break; } @@ -226,8 +236,7 @@ void hostapd_array_delete(uint32_t id) } -static void -blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const uint8_t *addr) { +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); @@ -244,8 +253,7 @@ static int decide_function(probe_entry *prob_req) { return 0; } - if(better_ap_available(prob_req->bssid_addr, prob_req->client_addr)) - { + if (better_ap_available(prob_req->bssid_addr, prob_req->client_addr, 0)) { return 0; } @@ -350,8 +358,7 @@ static int handle_auth_req(struct blob_attr *msg) { 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; } @@ -378,11 +385,12 @@ static int handle_probe_req(struct blob_attr *msg) { if(parse_to_probe_req(msg, &prob_req) == 0) { insert_to_array(prob_req, 1); - print_probe_array(); + //print_probe_array(); send_blob_attr_via_network(msg, "probe"); } //insert_to_list(prob_req, 1); //probe_entry tmp_probe = + probe_entry tmp_prob_req = insert_to_array(prob_req, 1); // send probe via network /*char *str; @@ -393,12 +401,17 @@ static int handle_probe_req(struct blob_attr *msg) { //print_probe_array(); - /* + // deny access - if (!decide_function(&tmp_probe)) { + + if (!dawn_metric.eval_probe_req) { + return 0; + } + + if (!decide_function(&tmp_prob_req)) { //printf("MAC WILL BE DECLINED!!!\n"); return UBUS_STATUS_UNKNOWN_ERROR; - }*/ + } //printf("MAC WILL BE ACCEPDTED!!!\n"); return 0; } @@ -472,7 +485,7 @@ int handle_network_msg(char* msg) if(parse_to_probe_req(data_buf.head, &entry) == 0) { insert_to_array(entry, 0); - print_probe_array(); + //print_probe_array(); } } else if (strncmp(method, "clients", 5) == 0) { //printf("METHOD CLIENTS\n"); @@ -555,8 +568,7 @@ static int add_subscriber(char *name) { return -1; } - if(hostapd_array_check_id(id)) - { + if (hostapd_array_check_id(id)) { return 0; } @@ -567,12 +579,11 @@ static int add_subscriber(char *name) { 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; - if(ctx == NULL) - { + if (ctx == NULL) { return 0; } @@ -592,10 +603,9 @@ static int subscribe_to_hostapd_interfaces(char *hostapd_dir) { return 0; } -static int subscribe_to_hostapd(char *hostapd_dir) { +static int subscribe_to_hostapd(const char *hostapd_dir) { - if(ctx == NULL) - { + if (ctx == NULL) { return 0; } @@ -617,7 +627,7 @@ static int subscribe_to_hostapd(char *hostapd_dir) { 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); @@ -650,8 +660,11 @@ int dawn_init_ubus(const char *ubus_socket, char *hostapd_dir) { //ubus_call_umdns(); + ubus_add_oject(); + uloop_run(); + close_socket(); ubus_free(ctx); @@ -762,6 +775,13 @@ 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]); + + 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) { @@ -776,16 +796,15 @@ static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_ if (!msg) return; - parse_to_clients(msg, 1, req->peer); send_blob_attr_via_network(msg, "clients"); + parse_to_clients(msg, 1, req->peer); print_client_array(); print_ap_array(); } static int ubus_get_clients() { - for(int i = 0; i <= hostapd_sock_last; i++) - { + 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); } @@ -794,6 +813,7 @@ static int ubus_get_clients() { 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); } @@ -818,8 +838,7 @@ 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); - for(int i = 0; i <= hostapd_sock_last; i++) - { + 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); } @@ -874,4 +893,88 @@ int ubus_send_probe_via_network(struct probe_entry_s probe_entry) { send_blob_attr_via_network(b_probe.head, "probe"); 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)); + */ } \ No newline at end of file diff --git a/src/utils/utils.c b/src/utils/utils.c index 323d4b2..8af0488 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -44,3 +44,19 @@ int convert_mac(char *in, char *out) { 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