mirror of
https://github.com/berlin-open-wireless-lab/DAWN.git
synced 2025-03-09 15:40:12 +00:00
1119 lines
No EOL
31 KiB
C
1119 lines
No EOL
31 KiB
C
#include "datastorage.h"
|
|
|
|
#include <limits.h>
|
|
#include <libubox/uloop.h>
|
|
|
|
#include "ubus.h"
|
|
#include "dawn_iwinfo.h"
|
|
#include "utils.h"
|
|
|
|
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
|
|
|
int go_next_help(char sort_order[], int i, probe_entry entry,
|
|
probe_entry next_entry);
|
|
|
|
int go_next(char sort_order[], int i, probe_entry entry,
|
|
probe_entry next_entry);
|
|
|
|
void remove_old_probe_entries(time_t current_time, long long int threshold);
|
|
|
|
int client_array_go_next(char sort_order[], int i, client entry,
|
|
client next_entry);
|
|
|
|
int client_array_go_next_help(char sort_order[], int i, client entry,
|
|
client next_entry);
|
|
|
|
void remove_old_client_entries(time_t current_time, long long int threshold);
|
|
|
|
int eval_probe_metric(struct probe_entry_s probe_entry);
|
|
|
|
int kick_client(struct client_s client_entry);
|
|
|
|
void ap_array_insert(ap entry);
|
|
|
|
ap ap_array_delete(ap entry);
|
|
|
|
void remove_old_ap_entries(time_t current_time, long long int threshold);
|
|
|
|
void print_ap_entry(ap entry);
|
|
|
|
int probe_array_update_rssi(uint8_t bssid_addr[], uint8_t client_addr[], uint32_t rssi);
|
|
|
|
int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]);
|
|
|
|
int mac_in_maclist(uint8_t mac[]);
|
|
|
|
int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare, int automatic_kick);
|
|
|
|
int probe_entry_last = -1;
|
|
int client_entry_last = -1;
|
|
int ap_entry_last = -1;
|
|
int mac_list_entry_last = -1;
|
|
|
|
void remove_probe_array_cb(struct uloop_timeout *t);
|
|
|
|
struct uloop_timeout probe_timeout = {
|
|
.cb = remove_probe_array_cb
|
|
};
|
|
|
|
void remove_client_array_cb(struct uloop_timeout *t);
|
|
|
|
struct uloop_timeout client_timeout = {
|
|
.cb = remove_client_array_cb
|
|
};
|
|
|
|
void remove_ap_array_cb(struct uloop_timeout *t);
|
|
|
|
struct uloop_timeout ap_timeout = {
|
|
.cb = remove_ap_array_cb
|
|
};
|
|
|
|
int eval_probe_metric(struct probe_entry_s probe_entry) {
|
|
|
|
int score = 0;
|
|
|
|
ap ap_entry = ap_array_get_ap(probe_entry.bssid_addr);
|
|
|
|
// check if ap entry is available
|
|
if (mac_is_equal(ap_entry.bssid_addr, probe_entry.bssid_addr)) {
|
|
score += probe_entry.ht_support && ap_entry.ht ? dawn_metric.ht_support : 0;
|
|
score += !probe_entry.ht_support && !ap_entry.ht ? dawn_metric.no_ht_support : 0;
|
|
score += probe_entry.vht_support && 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.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.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);
|
|
|
|
return score;
|
|
}
|
|
|
|
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
|
|
int i;
|
|
for (i = 0; i <= probe_entry_last; i++) {
|
|
if (mac_is_equal(probe_array[i].client_addr, client_addr)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// find own probe entry and calculate score
|
|
int j;
|
|
for (j = i; j <= probe_entry_last; j++) {
|
|
if (!mac_is_equal(probe_array[j].client_addr, client_addr)) {
|
|
// this shouldn't happen!
|
|
//return 1; // kick client!
|
|
//return 0;
|
|
break;
|
|
}
|
|
if (mac_is_equal(bssid_addr, probe_array[j].bssid_addr)) {
|
|
printf("Calculating own score!\n");
|
|
own_score = eval_probe_metric(probe_array[j]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// no entry for own ap
|
|
if (own_score == -1) {
|
|
return -1;
|
|
}
|
|
|
|
int k;
|
|
for (k = i; k <= probe_entry_last; k++) {
|
|
int score_to_compare;
|
|
|
|
if (!mac_is_equal(probe_array[k].client_addr, client_addr)) {
|
|
break;
|
|
}
|
|
|
|
if (mac_is_equal(bssid_addr, probe_array[k].bssid_addr)) {
|
|
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, 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;
|
|
for (i = 0; i <= client_entry_last; i++) {
|
|
if (mac_is_equal(client_array[i].bssid_addr, bssid)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Go threw clients
|
|
int j;
|
|
for (j = i; j <= client_entry_last; j++) {
|
|
if (!mac_is_equal(client_array[j].bssid_addr, bssid)) {
|
|
break;
|
|
}
|
|
|
|
// update rssi
|
|
int rssi = get_rssi_iwinfo(client_array[j].client_addr);
|
|
if (rssi != INT_MIN) {
|
|
pthread_mutex_unlock(&probe_array_mutex);
|
|
if (!probe_array_update_rssi(client_array[j].bssid_addr, client_array[j].client_addr, rssi)) {
|
|
printf("Failed to update RSSI!\n");
|
|
} else {
|
|
printf("RSSI UPDATED: RSSI: %d\n\n", rssi);
|
|
}
|
|
pthread_mutex_lock(&probe_array_mutex);
|
|
|
|
}
|
|
|
|
int do_kick = kick_client(client_array[j]);
|
|
|
|
// better ap available
|
|
if (do_kick > 0) {
|
|
printf("Better AP available. Kicking client:\n");
|
|
print_client_entry(client_array[j]);
|
|
printf("Check if client is active receiving!\n");
|
|
|
|
float rx_rate, tx_rate;
|
|
if (get_bandwidth_iwinfo(client_array[j].client_addr, &rx_rate, &tx_rate)) {
|
|
// only use rx_rate for indicating if transmission is going on
|
|
// <= 6MBits <- probably no transmission
|
|
// tx_rate has always some weird value so don't use ist
|
|
if (rx_rate > dawn_metric.bandwith_threshold) {
|
|
printf("Client is probably in active transmisison. Don't kick! RxRate is: %f\n", rx_rate);
|
|
continue;
|
|
}
|
|
}
|
|
printf("Client is probably NOT in active transmisison. KICK! RxRate is: %f\n", rx_rate);
|
|
|
|
del_client_interface(id, client_array[j].client_addr, 5, 1, 1000);
|
|
client_array_delete(client_array[j]);
|
|
|
|
// don't delete clients in a row. use update function again...
|
|
// -> chan_util update, ...
|
|
add_client_update_timer(timeout_config.update_client * 1000 / 4);
|
|
break;
|
|
|
|
// no entry in probe array for own bssid
|
|
} else if (do_kick == -1) {
|
|
printf("No Information about client. Force reconnect:\n");
|
|
print_client_entry(client_array[j]);
|
|
del_client_interface(id, client_array[j].client_addr, 0, 0, 0);
|
|
|
|
// ap is best
|
|
} else {
|
|
printf("AP is best. Client will stay:\n");
|
|
print_client_entry(client_array[j]);
|
|
}
|
|
}
|
|
|
|
printf("---------------------------\n");
|
|
|
|
pthread_mutex_unlock(&probe_array_mutex);
|
|
pthread_mutex_unlock(&client_array_mutex);
|
|
}
|
|
|
|
int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]) {
|
|
int i;
|
|
int found_in_array = 0;
|
|
|
|
if (client_entry_last == -1) {
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i <= client_entry_last; i++) {
|
|
|
|
if (mac_is_equal(bssid_addr, client_array[i].bssid_addr) &&
|
|
mac_is_equal(client_addr, client_array[i].client_addr)) {
|
|
found_in_array = 1;
|
|
break;
|
|
}
|
|
}
|
|
return found_in_array;
|
|
}
|
|
|
|
int client_array_go_next_help(char sort_order[], int i, client entry,
|
|
client next_entry) {
|
|
switch (sort_order[i]) {
|
|
// bssid-mac
|
|
case 'b':
|
|
return mac_is_greater(entry.bssid_addr, next_entry.bssid_addr) &&
|
|
mac_is_equal(entry.client_addr, next_entry.client_addr);
|
|
break;
|
|
|
|
// client-mac
|
|
case 'c':
|
|
return mac_is_greater(entry.client_addr, next_entry.client_addr);
|
|
break;
|
|
|
|
// frequency
|
|
// mac is 5 ghz or 2.4 ghz?
|
|
// case 'f':
|
|
// return //entry.freq < next_entry.freq &&
|
|
// entry.freq < 5000 &&
|
|
// next_entry.freq >= 5000 &&
|
|
// //entry.freq < 5 &&
|
|
// mac_is_equal(entry.client_addr, next_entry.client_addr);
|
|
// break;
|
|
|
|
// signal strength (RSSI)
|
|
//case 's':
|
|
// return entry.signal < next_entry.signal &&
|
|
// mac_is_equal(entry.client_addr, next_entry.client_addr);
|
|
// break;
|
|
|
|
default:
|
|
return 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int client_array_go_next(char sort_order[], int i, client entry,
|
|
client next_entry) {
|
|
int conditions = 1;
|
|
for (int j = 0; j < i; j++) {
|
|
i &= !(client_array_go_next(sort_order, j, entry, next_entry));
|
|
}
|
|
return conditions && client_array_go_next_help(sort_order, i, entry, next_entry);
|
|
}
|
|
|
|
void client_array_insert(client entry) {
|
|
if (client_entry_last == -1) {
|
|
client_array[0] = entry;
|
|
client_entry_last++;
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i <= client_entry_last; i++) {
|
|
if (!client_array_go_next("bc", 2, entry, client_array[i])) {
|
|
break;
|
|
}
|
|
}
|
|
for (int j = client_entry_last; j >= i; j--) {
|
|
if (j + 1 <= ARRAY_CLIENT_LEN) {
|
|
client_array[j + 1] = client_array[j];
|
|
}
|
|
}
|
|
client_array[i] = entry;
|
|
|
|
if (client_entry_last < ARRAY_CLIENT_LEN) {
|
|
client_entry_last++;
|
|
}
|
|
}
|
|
|
|
client *client_array_delete(client entry) {
|
|
|
|
int i;
|
|
int found_in_array = 0;
|
|
client *tmp = NULL;
|
|
|
|
if (client_entry_last == -1) {
|
|
return NULL;
|
|
}
|
|
|
|
for (i = 0; i <= client_entry_last; i++) {
|
|
if (mac_is_equal(entry.bssid_addr, client_array[i].bssid_addr) &&
|
|
mac_is_equal(entry.client_addr, client_array[i].client_addr)) {
|
|
found_in_array = 1;
|
|
tmp = &client_array[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int j = i; j <= client_entry_last; j++) {
|
|
client_array[j] = client_array[j + 1];
|
|
}
|
|
|
|
if (client_entry_last > -1 && found_in_array) {
|
|
client_entry_last--;
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
|
|
void probe_array_insert(probe_entry entry) {
|
|
if (probe_entry_last == -1) {
|
|
probe_array[0] = entry;
|
|
probe_entry_last++;
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i <= probe_entry_last; i++) {
|
|
if (!go_next(sort_string, SORT_NUM, entry, probe_array[i])) {
|
|
break;
|
|
}
|
|
}
|
|
for (int j = probe_entry_last; j >= i; j--) {
|
|
if (j + 1 <= PROBE_ARRAY_LEN) {
|
|
probe_array[j + 1] = probe_array[j];
|
|
}
|
|
}
|
|
probe_array[i] = entry;
|
|
|
|
if (probe_entry_last < PROBE_ARRAY_LEN) {
|
|
probe_entry_last++;
|
|
}
|
|
}
|
|
|
|
probe_entry probe_array_delete(probe_entry entry) {
|
|
int i;
|
|
int found_in_array = 0;
|
|
probe_entry tmp;
|
|
|
|
if (probe_entry_last == -1) {
|
|
return tmp;
|
|
}
|
|
|
|
for (i = 0; i <= probe_entry_last; i++) {
|
|
if (mac_is_equal(entry.bssid_addr, probe_array[i].bssid_addr) &&
|
|
mac_is_equal(entry.client_addr, probe_array[i].client_addr)) {
|
|
found_in_array = 1;
|
|
tmp = probe_array[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int j = i; j <= probe_entry_last; j++) {
|
|
probe_array[j] = probe_array[j + 1];
|
|
}
|
|
|
|
if (probe_entry_last > -1 && found_in_array) {
|
|
probe_entry_last--;
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
int probe_array_update_rssi(uint8_t bssid_addr[], uint8_t client_addr[], uint32_t rssi) {
|
|
|
|
int updated = 0;
|
|
|
|
if (probe_entry_last == -1) {
|
|
return 0;
|
|
}
|
|
|
|
|
|
pthread_mutex_lock(&probe_array_mutex);
|
|
for (int i = 0; i <= probe_entry_last; i++) {
|
|
if (mac_is_equal(bssid_addr, probe_array[i].bssid_addr) &&
|
|
mac_is_equal(client_addr, probe_array[i].client_addr)) {
|
|
probe_array[i].signal = rssi;
|
|
updated = 1;
|
|
ubus_send_probe_via_network(probe_array[i]);
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&probe_array_mutex);
|
|
|
|
return updated;
|
|
}
|
|
|
|
probe_entry probe_array_get_entry(uint8_t bssid_addr[], uint8_t client_addr[]) {
|
|
|
|
int i;
|
|
probe_entry tmp;
|
|
|
|
if (probe_entry_last == -1) {
|
|
return tmp;
|
|
}
|
|
|
|
pthread_mutex_lock(&probe_array_mutex);
|
|
for (i = 0; i <= probe_entry_last; i++) {
|
|
if (mac_is_equal(bssid_addr, probe_array[i].bssid_addr) &&
|
|
mac_is_equal(client_addr, probe_array[i].client_addr)) {
|
|
tmp = probe_array[i];
|
|
break;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&probe_array_mutex);
|
|
|
|
return tmp;
|
|
}
|
|
|
|
void print_probe_array() {
|
|
printf("------------------\n");
|
|
printf("Probe Entry Last: %d\n", probe_entry_last);
|
|
for (int i = 0; i <= probe_entry_last; i++) {
|
|
print_probe_entry(probe_array[i]);
|
|
}
|
|
printf("------------------\n");
|
|
}
|
|
|
|
probe_entry insert_to_array(probe_entry entry, int inc_counter) {
|
|
pthread_mutex_lock(&probe_array_mutex);
|
|
|
|
entry.time = time(0);
|
|
entry.counter = 0;
|
|
probe_entry tmp = probe_array_delete(entry);
|
|
|
|
if (mac_is_equal(entry.bssid_addr, tmp.bssid_addr)
|
|
&& mac_is_equal(entry.client_addr, tmp.client_addr)) {
|
|
entry.counter = tmp.counter;
|
|
}
|
|
|
|
if (inc_counter) {
|
|
|
|
entry.counter++;
|
|
}
|
|
|
|
probe_array_insert(entry);
|
|
|
|
pthread_mutex_unlock(&probe_array_mutex);
|
|
|
|
return entry;
|
|
}
|
|
|
|
ap insert_to_ap_array(ap entry) {
|
|
pthread_mutex_lock(&ap_array_mutex);
|
|
|
|
entry.time = time(0);
|
|
ap_array_delete(entry);
|
|
ap_array_insert(entry);
|
|
pthread_mutex_unlock(&ap_array_mutex);
|
|
|
|
return 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();
|
|
|
|
if (ap_entry_last == -1) {
|
|
return ret;
|
|
}
|
|
|
|
|
|
pthread_mutex_lock(&ap_array_mutex);
|
|
int i;
|
|
|
|
for (i = 0; i <= ap_entry_last; i++) {
|
|
if (mac_is_equal(bssid_addr, ap_array[i].bssid_addr) || mac_is_greater(ap_array[i].bssid_addr, bssid_addr)) {
|
|
break;
|
|
}
|
|
}
|
|
ret = ap_array[i];
|
|
pthread_mutex_unlock(&ap_array_mutex);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void ap_array_insert(ap entry) {
|
|
if (ap_entry_last == -1) {
|
|
ap_array[0] = entry;
|
|
ap_entry_last++;
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i <= ap_entry_last; i++) {
|
|
if (!mac_is_greater(entry.bssid_addr, ap_array[i].bssid_addr)) {
|
|
break;
|
|
}
|
|
}
|
|
for (int j = ap_entry_last; j >= i; j--) {
|
|
if (j + 1 <= ARRAY_AP_LEN) {
|
|
ap_array[j + 1] = ap_array[j];
|
|
}
|
|
}
|
|
ap_array[i] = entry;
|
|
|
|
if (ap_entry_last < ARRAY_AP_LEN) {
|
|
ap_entry_last++;
|
|
}
|
|
}
|
|
|
|
ap ap_array_delete(ap entry) {
|
|
int i;
|
|
int found_in_array = 0;
|
|
ap tmp;
|
|
|
|
if (ap_entry_last == -1) {
|
|
return tmp;
|
|
}
|
|
|
|
for (i = 0; i <= ap_entry_last; i++) {
|
|
if (mac_is_equal(entry.bssid_addr, ap_array[i].bssid_addr)) {
|
|
found_in_array = 1;
|
|
tmp = ap_array[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int j = i; j <= ap_entry_last; j++) {
|
|
ap_array[j] = ap_array[j + 1];
|
|
}
|
|
|
|
if (ap_entry_last > -1 && found_in_array) {
|
|
ap_entry_last--;
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
void remove_old_client_entries(time_t current_time, long long int threshold) {
|
|
for (int i = 0; i < probe_entry_last; i++) {
|
|
if (client_array[i].time < current_time - threshold) {
|
|
client_array_delete(client_array[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void remove_old_probe_entries(time_t current_time, long long int threshold) {
|
|
for (int i = 0; i < probe_entry_last; i++) {
|
|
if (probe_array[i].time < current_time - threshold) {
|
|
if (!is_connected(probe_array[i].bssid_addr, probe_array[i].client_addr))
|
|
probe_array_delete(probe_array[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void remove_old_ap_entries(time_t current_time, long long int threshold) {
|
|
for (int i = 0; i < probe_entry_last; i++) {
|
|
if (ap_array[i].time < current_time - threshold) {
|
|
ap_array_delete(ap_array[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void uloop_add_data_cbs() {
|
|
uloop_timeout_add(&probe_timeout);
|
|
uloop_timeout_add(&client_timeout);
|
|
uloop_timeout_add(&ap_timeout);
|
|
}
|
|
|
|
void remove_probe_array_cb(struct uloop_timeout *t) {
|
|
pthread_mutex_lock(&probe_array_mutex);
|
|
printf("[Thread] : Removing old entries!\n");
|
|
remove_old_probe_entries(time(0), timeout_config.remove_probe);
|
|
pthread_mutex_unlock(&probe_array_mutex);
|
|
uloop_timeout_set(&probe_timeout, timeout_config.remove_probe * 1000);
|
|
}
|
|
|
|
void remove_client_array_cb(struct uloop_timeout *t) {
|
|
pthread_mutex_lock(&client_array_mutex);
|
|
printf("[Thread] : Removing old client entries!\n");
|
|
remove_old_client_entries(time(0), timeout_config.update_client);
|
|
pthread_mutex_unlock(&client_array_mutex);
|
|
uloop_timeout_set(&client_timeout, timeout_config.update_client * 1000);
|
|
}
|
|
|
|
void remove_ap_array_cb(struct uloop_timeout *t) {
|
|
pthread_mutex_lock(&ap_array_mutex);
|
|
printf("[ULOOP] : Removing old ap entries!\n");
|
|
remove_old_ap_entries(time(0), timeout_config.remove_ap);
|
|
pthread_mutex_unlock(&ap_array_mutex);
|
|
uloop_timeout_set(&ap_timeout, timeout_config.remove_ap * 1000);
|
|
}
|
|
|
|
void insert_client_to_array(client entry) {
|
|
pthread_mutex_lock(&client_array_mutex);
|
|
entry.time = time(0);
|
|
|
|
client_array_delete(entry);
|
|
client_array_insert(entry);
|
|
|
|
pthread_mutex_unlock(&client_array_mutex);
|
|
}
|
|
|
|
void insert_macs_from_file()
|
|
{
|
|
FILE * fp;
|
|
char * line = NULL;
|
|
size_t len = 0;
|
|
ssize_t read;
|
|
|
|
fp = fopen("/etc/dawn/mac_list", "r");
|
|
if (fp == NULL)
|
|
exit(EXIT_FAILURE);
|
|
|
|
while ((read = getline(&line, &len, fp)) != -1) {
|
|
printf("Retrieved line of length %zu :\n", read);
|
|
printf("%s", line);
|
|
|
|
int tmp_int_mac[ETH_ALEN];
|
|
sscanf(line, MACSTR, STR2MAC(tmp_int_mac));
|
|
|
|
mac_list_entry_last++;
|
|
for (int i = 0; i < ETH_ALEN; ++i) {
|
|
mac_list[mac_list_entry_last][i] = (uint8_t) tmp_int_mac[i];
|
|
}
|
|
}
|
|
|
|
printf("Printing MAC List:\n");
|
|
for(int i = 0; i <= mac_list_entry_last; i++)
|
|
{
|
|
char mac_buf_target[20];
|
|
sprintf(mac_buf_target, MACSTR, MAC2STR(mac_list[i]));
|
|
printf("%d: %s\n", i, mac_buf_target);
|
|
}
|
|
|
|
fclose(fp);
|
|
if (line)
|
|
free(line);
|
|
//exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
int insert_to_maclist(uint8_t mac[])
|
|
{
|
|
if(mac_in_maclist(mac))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
mac_list_entry_last++;
|
|
for (int i = 0; i < ETH_ALEN; ++i) {
|
|
mac_list[mac_list_entry_last][i] = mac[i];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int mac_in_maclist(uint8_t mac[])
|
|
{
|
|
for(int i = 0; i <= mac_list_entry_last; i++)
|
|
{
|
|
if(mac_is_equal(mac, mac_list[i]))
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
node *delete_probe_req(node **ret_remove, node *head, uint8_t bssid_addr[],
|
|
uint8_t client_addr[]);
|
|
|
|
int mac_is_first_in_list(node *head, uint8_t bssid_addr[],
|
|
uint8_t client_addr[]);
|
|
|
|
node *remove_node(node *head, node *curr, node *prev);
|
|
|
|
node *remove_old_entries(node *head, time_t current_time,
|
|
long long int threshold);
|
|
|
|
void print_list_with_head(node *head);
|
|
|
|
void insert_to_list(probe_entry entry, int inc_counter) {
|
|
pthread_mutex_lock(&list_mutex);
|
|
|
|
entry.time = time(0);
|
|
entry.counter = 0;
|
|
|
|
|
|
// first delete probe request
|
|
// probe_list_head = remove_old_entries(probe_list_head, time(0),
|
|
// TIME_THRESHOLD);
|
|
node *tmp_probe_req = NULL;
|
|
probe_list_head = delete_probe_req(&tmp_probe_req, probe_list_head,
|
|
entry.bssid_addr, entry.client_addr);
|
|
|
|
if (tmp_probe_req) {
|
|
// local ubus
|
|
tmp_probe_req->data.signal = entry.signal;
|
|
tmp_probe_req->data.time = entry.time;
|
|
if (inc_counter) {
|
|
// when network don't increase counter...
|
|
tmp_probe_req->data.counter++;
|
|
}
|
|
|
|
// is this correct?
|
|
probe_list_head = insert(probe_list_head, tmp_probe_req->data);
|
|
free(tmp_probe_req);
|
|
} else {
|
|
printf("New entry!\n");
|
|
probe_list_head = insert(probe_list_head, entry);
|
|
}
|
|
|
|
pthread_mutex_unlock(&list_mutex);
|
|
}
|
|
|
|
int go_next_help(char sort_order[], int i, probe_entry entry,
|
|
probe_entry next_entry) {
|
|
switch (sort_order[i]) {
|
|
// bssid-mac
|
|
case 'b':
|
|
return mac_is_greater(entry.bssid_addr, next_entry.bssid_addr) &&
|
|
mac_is_equal(entry.client_addr, next_entry.client_addr);
|
|
break;
|
|
|
|
// client-mac
|
|
case 'c':
|
|
return mac_is_greater(entry.client_addr, next_entry.client_addr);
|
|
break;
|
|
|
|
// frequency
|
|
// mac is 5 ghz or 2.4 ghz?
|
|
case 'f':
|
|
return //entry.freq < next_entry.freq &&
|
|
entry.freq < 5000 &&
|
|
next_entry.freq >= 5000 &&
|
|
//entry.freq < 5 &&
|
|
mac_is_equal(entry.client_addr, next_entry.client_addr);
|
|
break;
|
|
|
|
// signal strength (RSSI)
|
|
case 's':
|
|
return entry.signal < next_entry.signal &&
|
|
mac_is_equal(entry.client_addr, next_entry.client_addr);
|
|
break;
|
|
|
|
default:
|
|
return 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int go_next(char sort_order[], int i, probe_entry entry,
|
|
probe_entry next_entry) {
|
|
int conditions = 1;
|
|
for (int j = 0; j < i; j++) {
|
|
i &= !(go_next(sort_order, j, entry, next_entry));
|
|
}
|
|
return conditions && go_next_help(sort_order, i, entry, next_entry);
|
|
}
|
|
|
|
node *insert(node *head, probe_entry entry) {
|
|
node *temp, *prev, *next;
|
|
temp = (node *) malloc(sizeof(node));
|
|
temp->data = entry;
|
|
temp->ptr = NULL;
|
|
|
|
// length of sorting string
|
|
// char sort_string[] = "cfsb";
|
|
int i = 0;
|
|
|
|
if (!head) {
|
|
head = temp;
|
|
} else {
|
|
prev = NULL;
|
|
next = head;
|
|
while (next) {
|
|
if (go_next(sort_string, i, entry, next->data)) {
|
|
prev = next;
|
|
next = next->ptr;
|
|
} else if (i < strlen(sort_string)) {
|
|
i++;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
if (!next) {
|
|
prev->ptr = temp;
|
|
} else {
|
|
if (prev) {
|
|
temp->ptr = prev->ptr;
|
|
prev->ptr = temp;
|
|
} else {
|
|
temp->ptr = head;
|
|
head = temp;
|
|
}
|
|
}
|
|
}
|
|
return head;
|
|
}
|
|
|
|
node *delete_probe_req(node **ret_remove, node *head, uint8_t bssid_addr[],
|
|
uint8_t client_addr[]) {
|
|
if (!head) {
|
|
return head;
|
|
}
|
|
|
|
if (mac_is_equal(client_addr, head->data.client_addr) &&
|
|
mac_is_equal(bssid_addr, head->data.bssid_addr)) {
|
|
node *temp = head;
|
|
head = head->ptr;
|
|
*ret_remove = temp;
|
|
// don't free pointer
|
|
// free(temp);
|
|
return head;
|
|
}
|
|
|
|
node *prev = NULL;
|
|
node *next = head;
|
|
while (next) {
|
|
if (mac_is_greater(next->data.client_addr, client_addr)) {
|
|
break;
|
|
}
|
|
|
|
if (mac_is_equal(client_addr, next->data.client_addr) &&
|
|
mac_is_equal(bssid_addr, next->data.bssid_addr)) {
|
|
node *temp = next;
|
|
prev->ptr = next->ptr;
|
|
// free(temp);
|
|
*ret_remove = temp;
|
|
return head;
|
|
}
|
|
prev = next;
|
|
next = next->ptr;
|
|
}
|
|
return head;
|
|
}
|
|
|
|
void *remove_thread(void *arg) {
|
|
while (1) {
|
|
sleep(TIME_THRESHOLD);
|
|
pthread_mutex_lock(&list_mutex);
|
|
printf("[Thread] : Removing old entries!\n");
|
|
probe_list_head =
|
|
remove_old_entries(probe_list_head, time(0), TIME_THRESHOLD);
|
|
pthread_mutex_unlock(&list_mutex);
|
|
// print_list();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
node *remove_old_entries(node *head, time_t current_time,
|
|
long long int threshold) {
|
|
if (head) {
|
|
node *prev = NULL;
|
|
node *next = head;
|
|
while (next) {
|
|
if (next->data.time < current_time - threshold) {
|
|
head = remove_node(head, next, prev);
|
|
// print_list_with_head(head);
|
|
if (prev == NULL) // removed head
|
|
{
|
|
next = head;
|
|
} else {
|
|
next = prev->ptr;
|
|
}
|
|
} else {
|
|
prev = next;
|
|
next = next->ptr;
|
|
}
|
|
}
|
|
}
|
|
return head;
|
|
}
|
|
|
|
// return headpointer
|
|
node *remove_node(node *head, node *curr, node *prev) {
|
|
if (curr == head) {
|
|
node *temp = head;
|
|
head = head->ptr;
|
|
free(temp);
|
|
} else {
|
|
node *temp = curr;
|
|
prev->ptr = curr->ptr;
|
|
free(temp);
|
|
}
|
|
// printf("Removed old entry!\n");
|
|
return head;
|
|
}
|
|
|
|
int mac_is_first_in_list(node *head, uint8_t bssid_addr[],
|
|
uint8_t client_addr[]) {
|
|
if (!head) {
|
|
return 1;
|
|
}
|
|
node *next = head;
|
|
while (next) {
|
|
if (mac_is_greater(next->data.client_addr, client_addr)) {
|
|
break;
|
|
}
|
|
|
|
if (mac_is_equal(client_addr, next->data.client_addr)) {
|
|
print_probe_entry(next->data);
|
|
return mac_is_equal(bssid_addr, next->data.bssid_addr);
|
|
}
|
|
next = next->ptr;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int mac_first_in_probe_list(uint8_t bssid_addr[], uint8_t client_addr[]) {
|
|
pthread_mutex_lock(&list_mutex);
|
|
int ret = mac_is_first_in_list(probe_list_head, bssid_addr, client_addr);
|
|
pthread_mutex_unlock(&list_mutex);
|
|
return ret;
|
|
}
|
|
|
|
void free_list(node *head) {
|
|
node *prev = head;
|
|
node *cur = head;
|
|
while (cur) {
|
|
prev = cur;
|
|
cur = prev->ptr;
|
|
free(prev);
|
|
}
|
|
}
|
|
|
|
int mac_is_equal(uint8_t addr1[], uint8_t addr2[]) {
|
|
return memcmp(addr1, addr2, ETH_ALEN * sizeof(uint8_t)) == 0;
|
|
}
|
|
|
|
int mac_is_greater(uint8_t addr1[], uint8_t addr2[]) {
|
|
for (int i = 0; i < ETH_ALEN; i++) {
|
|
if (addr1[i] > addr2[i]) {
|
|
return 1;
|
|
}
|
|
if (addr1[i] < addr2[i]) {
|
|
return 0;
|
|
}
|
|
|
|
// if equal continue...
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void print_list_with_head(node *head) {
|
|
pthread_mutex_lock(&list_mutex);
|
|
printf("------------------\n");
|
|
if (head) {
|
|
node *next;
|
|
next = head;
|
|
while (next) {
|
|
print_probe_entry(next->data);
|
|
next = next->ptr;
|
|
}
|
|
}
|
|
printf("------------------\n");
|
|
pthread_mutex_unlock(&list_mutex);
|
|
}
|
|
|
|
void print_list() {
|
|
pthread_mutex_lock(&list_mutex);
|
|
printf("------------------\n");
|
|
node *head = probe_list_head;
|
|
if (head) {
|
|
node *next;
|
|
next = head;
|
|
while (next) {
|
|
print_probe_entry(next->data);
|
|
next = next->ptr;
|
|
}
|
|
}
|
|
printf("------------------\n");
|
|
pthread_mutex_unlock(&list_mutex);
|
|
}
|
|
|
|
void print_probe_entry(probe_entry entry) {
|
|
char mac_buf_ap[20];
|
|
char mac_buf_client[20];
|
|
char mac_buf_target[20];
|
|
|
|
sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr));
|
|
sprintf(mac_buf_client, MACSTR, MAC2STR(entry.client_addr));
|
|
sprintf(mac_buf_target, MACSTR, MAC2STR(entry.target_addr));
|
|
|
|
printf(
|
|
"bssid_addr: %s, client_addr: %s, signal: %d, freq: "
|
|
"%d, counter: %d, vht: %d\n",
|
|
mac_buf_ap, mac_buf_client, entry.signal, entry.freq, entry.counter, entry.vht_support);
|
|
}
|
|
|
|
void print_auth_entry(auth_entry entry) {
|
|
char mac_buf_ap[20];
|
|
char mac_buf_client[20];
|
|
char mac_buf_target[20];
|
|
|
|
sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr));
|
|
sprintf(mac_buf_client, MACSTR, MAC2STR(entry.client_addr));
|
|
sprintf(mac_buf_target, MACSTR, MAC2STR(entry.target_addr));
|
|
|
|
printf(
|
|
"bssid_addr: %s, client_addr: %s, signal: %d, freq: "
|
|
"%d\n",
|
|
mac_buf_ap, mac_buf_client, entry.signal, entry.freq);
|
|
}
|
|
|
|
void print_client_entry(client entry) {
|
|
char mac_buf_ap[20];
|
|
char mac_buf_client[20];
|
|
|
|
sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr));
|
|
sprintf(mac_buf_client, MACSTR, MAC2STR(entry.client_addr));
|
|
|
|
printf("bssid_addr: %s, client_addr: %s, freq: %d, ht_supported: %d, vht_supported: %d, ht: %d, vht: %d\n",
|
|
mac_buf_ap, mac_buf_client, entry.freq, entry.ht_supported, entry.vht_supported, entry.ht, entry.vht);
|
|
}
|
|
|
|
void print_client_array() {
|
|
printf("--------Clients------\n");
|
|
printf("Client Entry Last: %d\n", client_entry_last);
|
|
for (int i = 0; i <= client_entry_last; i++) {
|
|
print_client_entry(client_array[i]);
|
|
}
|
|
printf("------------------\n");
|
|
}
|
|
|
|
void print_ap_entry(ap entry) {
|
|
char mac_buf_ap[20];
|
|
|
|
sprintf(mac_buf_ap, MACSTR, MAC2STR(entry.bssid_addr));
|
|
printf("bssid_addr: %s, freq: %d, ht: %d, vht: %d, chan_utilz: %d\n",
|
|
mac_buf_ap, entry.freq, entry.ht, entry.vht, entry.channel_utilization);
|
|
}
|
|
|
|
void print_ap_array() {
|
|
printf("--------APs------\n");
|
|
for (int i = 0; i <= ap_entry_last; i++) {
|
|
print_ap_entry(ap_array[i]);
|
|
}
|
|
printf("------------------\n");
|
|
} |