Merge branch 'feature/refactor_config_handling' into feature/add_ubus_methods

This commit is contained in:
PolynomialDivision 2017-12-22 13:53:56 +01:00
commit a78891d0df
21 changed files with 579 additions and 481 deletions

View file

@ -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'

View file

@ -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!"
}

View file

@ -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)

View file

@ -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';

View file

@ -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);

View file

@ -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);

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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,
@ -68,3 +68,14 @@ 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");
return -1;
}
return 0;
}

View file

@ -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);
}

View file

@ -4,7 +4,7 @@
#include <libubox/uloop.h>
#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);

129
src/utils/dawn_iwinfo.c Normal file
View file

@ -0,0 +1,129 @@
#include "dawn_iwinfo.h"
#include <limits.h>
#include <iwinfo.h>
#include <dirent.h>
#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;
}

View file

@ -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;
}

View file

@ -1,72 +0,0 @@
#include "rssi.h"
#include <limits.h>
#include <iwinfo.h>
#include <dirent.h>
#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;
}

View file

@ -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);
}