diff --git a/files/dawn.config b/files/dawn.config index 4051456..4009ec7 100644 --- a/files/dawn.config +++ b/files/dawn.config @@ -1,30 +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 '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 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 '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 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/src/CMakeLists.txt b/src/CMakeLists.txt index 9633969..ae445a9 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,10 +39,10 @@ SET(SOURCES crypto/base64.c include/base64.h - utils/utils.c include/rssi.h utils/rssi.c) + utils/utils.c include/dawn_iwinfo.h utils/dawn_iwinfo.c) SET(LIBS - ubox ubus json-c blobmsg_json config uci gcrypt ssl crypto iwinfo) + ubox ubus json-c blobmsg_json config uci gcrypt iwinfo) ADD_EXECUTABLE(dawn ${SOURCES} utils/dawn_uci.c include/dawn_uci.h) 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 dce9263..492bce6 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -37,11 +37,18 @@ struct probe_metric_s { 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 { @@ -52,6 +59,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 ---------------- @@ -137,6 +153,7 @@ typedef struct ap_s { uint8_t vht; uint32_t channel_utilization; time_t time; + uint32_t station_count; } ap; // ---------------- Defines ---------------- @@ -179,14 +196,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/rssi.h b/src/include/dawn_iwinfo.h similarity index 69% rename from src/include/rssi.h rename to src/include/dawn_iwinfo.h index 863f25b..215d817 100644 --- a/src/include/rssi.h +++ b/src/include/dawn_iwinfo.h @@ -8,4 +8,6 @@ int get_rssi_iwinfo(__uint8_t *client_addr); +int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate); + #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 ce91d3a..5c169fc 100644 --- a/src/include/ubus.h +++ b/src/include/ubus.h @@ -8,7 +8,7 @@ #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); @@ -24,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(); @@ -32,4 +32,6 @@ 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); + #endif diff --git a/src/main.c b/src/main.c index 1d4805e..0942347 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,7 @@ #include "networksocket.h" #include "ubus.h" #include "dawn_uci.h" +#include "dawn_uci.h" #include "crypto.h" #define BUFSIZE 17 @@ -21,6 +22,8 @@ struct sigaction newSigAction; void daemon_shutdown() { // kill threads + close_socket(); + uci_clear(); printf("Cancelling Threads!\n"); uloop_cancelled = true; @@ -51,69 +54,32 @@ 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; - } - } + // int ch; 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 */ + sigaction(SIGHUP, &newSigAction, NULL); + sigaction(SIGTERM, &newSigAction, NULL); + sigaction(SIGINT, &newSigAction, 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(shared_key, iv); + 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(); + if (pthread_mutex_init(&list_mutex, NULL) != 0) { printf("\n mutex init failed\n"); return 1; @@ -134,11 +100,10 @@ int main(int argc, char **argv) { return 1; } - init_socket_runopts(opt_broadcast_ip, opt_broadcast_port, 1); + init_socket_runopts(net_config.broadcast_ip, net_config.broadcast_port, net_config.bool_multicast); insert_macs_from_file(); - - dawn_init_ubus(ubus_socket, opt_hostapd_dir); + 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 6258ae5..4833431 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; @@ -235,4 +237,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 2eb08f4..b35c6ac 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -4,7 +4,7 @@ #include #include "ubus.h" -#include "rssi.h" +#include "dawn_iwinfo.h" #include "utils.h" #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] @@ -43,6 +43,8 @@ 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; @@ -78,11 +80,13 @@ int eval_probe_metric(struct probe_entry_s probe_entry) { score += !probe_entry.ht_support && !ap_entry.ht ? dawn_metric.no_ht_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); print_probe_entry(probe_entry); @@ -90,7 +94,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 @@ -111,6 +136,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; } @@ -123,26 +149,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 !mac_in_maclist(client_entry.client_addr) && 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; @@ -172,14 +217,36 @@ 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]); - del_client_interface(id, client_array[j].client_addr, 5, 1, 60000); + 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); + + 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 (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); @@ -191,6 +258,8 @@ void kick_clients(uint8_t bssid[], uint32_t id) { } } + printf("---------------------------\n"); + pthread_mutex_unlock(&probe_array_mutex); pthread_mutex_unlock(&client_array_mutex); } @@ -459,11 +528,11 @@ 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)); - printf("Try to find: %s\n", bssid_mac_string); - printf("in\n"); - print_ap_array(); + //char bssid_mac_string[20]; + //sprintf(bssid_mac_string, MACSTR, 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; @@ -561,8 +630,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); @@ -576,8 +644,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); diff --git a/src/utils/dawn_iwinfo.c b/src/utils/dawn_iwinfo.c new file mode 100644 index 0000000..7984f31 --- /dev/null +++ b/src/utils/dawn_iwinfo.c @@ -0,0 +1,129 @@ +#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_bandwith(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate); + +#define IWINFO_BUFSIZE 24 * 1024 + +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_bandwith(entry->d_name, client_addr, rx_rate, tx_rate)) { + sucess = 1; + break; + } + } + } + closedir(dirp); + return sucess; +} + +int get_bandwith(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 186578c..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,96 +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_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/rssi.c b/src/utils/rssi.c deleted file mode 100644 index 7474613..0000000 --- a/src/utils/rssi.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "rssi.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); - -#define IWINFO_BUFSIZE 24 * 1024 - -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 -1; - } - - 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/ubus.c b/src/utils/ubus.c index caba791..d12be7b 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -24,13 +24,12 @@ static struct blob_buf b; void update_clients(struct uloop_timeout *t); -struct uloop_timeout hostapd_timer = { - .cb = update_hostapd_sockets -}; - 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]; @@ -81,6 +80,7 @@ enum { CLIENT_TABLE_HT, CLIENT_TABLE_VHT, CLIENT_TABLE_CHAN_UTIL, + CLIENT_TABLE_NUM_STA, __CLIENT_TABLE_MAX, }; @@ -91,6 +91,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 { @@ -132,7 +133,7 @@ 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(); @@ -142,16 +143,19 @@ add_mac(struct ubus_context *ctx, struct ubus_object *obj, 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(); -int hostapd_array_check_id(uint32_t id) -{ - for(int i = 0; i <= hostapd_sock_last; i++) - { - if(hostapd_sock_arr[i] == 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; } } @@ -159,21 +163,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; @@ -181,9 +182,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; } @@ -217,8 +217,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; } @@ -309,8 +308,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; } @@ -337,7 +335,7 @@ static int handle_probe_req(struct blob_attr *msg) { 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 = insert_to_array(prob_req, 1); // send probe via network @@ -348,12 +346,17 @@ static int handle_probe_req(struct blob_attr *msg) { printf("[WC] Hostapd-Probe: %s : %s\n", "probe", str); //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; } @@ -384,8 +387,7 @@ static int add_subscriber(char *name) { return -1; } - if(hostapd_array_check_id(id)) - { + if (hostapd_array_check_id(id)) { return 0; } @@ -396,12 +398,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; } @@ -421,10 +422,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; } @@ -439,14 +439,14 @@ static int subscribe_to_hostapd(char *hostapd_dir) { hostapd_event.remove_cb = hostapd_handle_remove; hostapd_event.cb = hostapd_notify; - //subscribe_to_hostapd_interfaces(hostapd_dir); + 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); @@ -578,6 +578,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) { @@ -592,17 +599,17 @@ static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_ if (!msg) return; - parse_to_clients(msg, 1, req->peer); - char *str = blobmsg_format_json(msg, true); send_string_enc(str); + + 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); } @@ -611,10 +618,12 @@ 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); } void update_hostapd_sockets(struct uloop_timeout *t) { + printf("Updating hostapd sockets!\n"); subscribe_to_hostapd_interfaces(hostapd_dir_glob); uloop_timeout_set(&hostapd_timer, timeout_config.update_hostapd * 1000); } @@ -635,8 +644,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); }