Merge pull request #3 from berlin-open-wireless-lab/feature/clients_exchange

Feature/clients exchange
This commit is contained in:
Polynomdivision 2017-07-17 13:33:29 +02:00 committed by GitHub
commit c5ec149f09
7 changed files with 436 additions and 23 deletions

View file

@ -27,12 +27,50 @@ typedef struct probe_entry_s {
int counter;
} probe_entry;
typedef struct {
uint32_t freq;
} client_request;
typedef struct client_s {
uint8_t bssid_addr[ETH_ALEN];
uint8_t client_addr[ETH_ALEN];
uint32_t freq;
uint8_t auth;
uint8_t assoc;
uint8_t authorized;
uint8_t preauth;
uint8_t wds;
uint8_t wmm;
uint8_t ht;
uint8_t vht;
uint8_t wps;
uint8_t mfp;
time_t time;
uint32_t aid;
} client;
// Array
#define ARRAY_CLIENT_LEN 1000
#define TIME_THRESHOLD_CLIENT 60
struct client_s client_array[ARRAY_CLIENT_LEN];
pthread_mutex_t client_array_mutex;
void insert_client_to_array(client entry);
void client_array_insert(client entry);
client* client_array_delete(client entry);
void print_client_array();
void print_client_entry(client entry);
void *remove_client_array_thread(void *arg);
#define ARRAY_LEN 1000
struct probe_entry_s probe_array[ARRAY_LEN];
pthread_mutex_t probe_array_mutex;
void insert_to_array(probe_entry entry, int inc_counter);
void probe_array_insert(probe_entry entry);
@ -40,10 +78,6 @@ probe_entry* probe_array_delete(probe_entry entry);
void print_array();
void *remove_array_thread(void *arg);
pthread_mutex_t probe_array_mutex;

View file

@ -7,5 +7,9 @@
int dawn_init_ubus(const char *ubus_socket, char *hostapd_dir);
int parse_to_probe_req(struct blob_attr *msg, probe_entry *prob_req);
int parse_to_clients(struct blob_attr *msg);
void *update_clients_thread(void *arg);
char* hostapd_dir_glob;
#endif

View file

@ -2,6 +2,8 @@
#define __DAWN_UTILS_H
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define STR2MAC(a) &(a)[0], &(a)[1], &(a)[2], &(a)[3], &(a)[4], &(a)[5]
static int hex_to_bin(char ch) {
if ((ch >= '0') && (ch <= '9')) return ch - '0';

View file

@ -35,6 +35,7 @@ int main(int argc, char **argv) {
case 'h':
snprintf(opt_hostapd_dir, BUFSIZE_DIR, "%s", optarg);
printf("hostapd dir: %s\n", opt_hostapd_dir);
hostapd_dir_glob = optarg;
default:
break;
}
@ -53,10 +54,24 @@ int main(int argc, char **argv) {
return 1;
}
if (pthread_mutex_init(&client_array_mutex, NULL) != 0) {
printf("\n mutex init failed\n");
return 1;
}
init_socket_runopts(opt_broadcast_ip, opt_broadcast_port, 0);
pthread_t tid;
pthread_create(&tid, NULL, &remove_array_thread, NULL);
pthread_t tid_probe;
pthread_create(&tid_probe, NULL, &remove_array_thread, NULL);
pthread_t tid_client;
pthread_create(&tid_client, NULL, &remove_client_array_thread, NULL);
pthread_t tid_get_client;
pthread_create(&tid_get_client, NULL, &update_clients_thread, NULL);
//pthread_create(&tid, NULL, &remove_thread, NULL);
dawn_init_ubus(ubus_socket, opt_hostapd_dir);

View file

@ -16,7 +16,7 @@
#include "ubus.h"
/* Network Defines */
#define MAX_RECV_STRING 255
#define MAX_RECV_STRING 1500
#define NET_CONFIG_PATH "/etc/wlancontroller/networkconfig.conf"
/* Network Attributes */
@ -69,13 +69,31 @@ void *receive_msg(void *args) {
blob_buf_init(&b, 0);
blobmsg_add_json_from_string(&b, recv_string);
recv_string[recv_string_len] = '\0';
//recv_string[recv_string_len] = '\0';
char *str;
str = blobmsg_format_json(b.head, true);
printf("Parsed: '%s'\n", str);
parse_to_probe_req(b.head, &prob_req);
insert_to_array(prob_req, 0);
/*
TODO: REFACTOR THIS!!! (just workaround)
OTHERWISE NULLPOINTER?!
*/
if(strstr(str, "clients") != NULL) {
parse_to_clients(b.head);
} else
{
if(parse_to_probe_req(b.head, &prob_req) == 0)
{
insert_to_array(prob_req, 0);
}
}
//if(parse_to_probe_req(b.head, &prob_req) == 0)
//{
// insert_to_array(prob_req, 0);
//}
// insert to list
//insert_to_list(prob_req, 0);

View file

@ -11,7 +11,126 @@ int mac_is_greater(uint8_t addr1[], uint8_t addr2[]);
void print_probe_entry(probe_entry 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 probe_entry_last = -1;
int client_entry_last = -1;
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_LEN)
{
client_array[j + 1] = client_array[j];
}
}
client_array[i] = entry;
if(client_entry_last < ARRAY_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)
@ -114,6 +233,17 @@ void insert_to_array(probe_entry entry, int inc_counter)
pthread_mutex_unlock(&probe_array_mutex);
}
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++)
@ -136,8 +266,29 @@ void *remove_array_thread(void *arg) {
return 0;
}
void *remove_client_array_thread(void *arg) {
while (1) {
sleep(TIME_THRESHOLD_CLIENT);
pthread_mutex_lock(&client_array_mutex);
printf("[Thread] : Removing old client entries!\n");
remove_old_client_entries(time(0), TIME_THRESHOLD_CLIENT);
pthread_mutex_unlock(&client_array_mutex);
}
return 0;
}
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);
}
@ -462,4 +613,25 @@ void print_probe_entry(probe_entry entry) {
"%d, counter: %d\n",
mac_buf_ap, mac_buf_client, mac_buf_target, entry.signal, entry.freq,
entry.counter);
}
void print_client_entry(client entry) {
char mac_buf_ap[20];
char mac_buf_client[20];
sprintf(mac_buf_ap, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.bssid_addr));
sprintf(mac_buf_client, "%x:%x:%x:%x:%x:%x", MAC2STR(entry.client_addr));
printf("bssid_addr: %s, client_addr: %s, freq: %d\n",
mac_buf_ap, mac_buf_client, entry.freq);
}
void print_client_array() {
printf("--------Clients------\n");
printf("Probe Entry Last: %d\n", client_entry_last);
for(int i = 0; i <= client_entry_last; i++)
{
print_client_entry(client_array[i]);
}
printf("------------------\n");
}

View file

@ -33,6 +33,52 @@ static const struct blobmsg_policy prob_policy[__PROB_MAX] = {
[PROB_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32},
};
enum {
CLIENT_TABLE,
CLIENT_TABLE_BSSID,
CLIENT_TABLE_FREQ,
__CLIENT_TABLE_MAX,
};
static const struct blobmsg_policy client_table_policy[__CLIENT_TABLE_MAX] = {
[CLIENT_TABLE] = {.name = "clients", .type = BLOBMSG_TYPE_TABLE},
[CLIENT_TABLE_BSSID] = {.name = "bssid", .type = BLOBMSG_TYPE_STRING},
[CLIENT_TABLE_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32},
};
enum {
//CLIENT_TABLE,
//CLIENT_TABLE_FREQ,
CLIENT_AUTH,
CLIENT_ASSOC,
CLIENT_AUTHORIZED,
CLIENT_PREAUTH,
CLIENT_WDS,
CLIENT_WMM,
CLIENT_HT,
CLIENT_VHT,
CLIENT_WPS,
CLIENT_MFP,
CLIENT_AID,
__CLIENT_MAX,
};
static const struct blobmsg_policy client_policy[__CLIENT_MAX] = {
//[CLIENT_TABLE] = {.name = "clients", .type = BLOBMSG_TYPE_TABLE},
//[CLIENT_TABLE_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32},
[CLIENT_AUTH] = {.name = "auth", .type = BLOBMSG_TYPE_INT8},
[CLIENT_ASSOC] = {.name = "assoc", .type = BLOBMSG_TYPE_INT8},
[CLIENT_AUTHORIZED] = {.name = "authorized", .type = BLOBMSG_TYPE_INT8},
[CLIENT_PREAUTH] = {.name = "preauth", .type = BLOBMSG_TYPE_INT8},
[CLIENT_WDS] = {.name = "wds", .type = BLOBMSG_TYPE_INT8},
[CLIENT_WMM] = {.name = "wmm", .type = BLOBMSG_TYPE_INT8},
[CLIENT_HT] = {.name = "ht", .type = BLOBMSG_TYPE_INT8},
[CLIENT_VHT] = {.name = "vht", .type = BLOBMSG_TYPE_INT8},
[CLIENT_WPS] = {.name = "wps", .type = BLOBMSG_TYPE_INT8},
[CLIENT_MFP] = {.name = "mfp", .type = BLOBMSG_TYPE_INT8},
[CLIENT_AID] = {.name = "aid", .type = BLOBMSG_TYPE_INT32},
};
/* Function Definitions */
static void hostapd_handle_remove(struct ubus_context *ctx,
struct ubus_subscriber *s, uint32_t id);
@ -66,6 +112,7 @@ static void hostapd_handle_remove(struct ubus_context *ctx,
int parse_to_probe_req(struct blob_attr *msg, probe_entry *prob_req) {
struct blob_attr *tb[__PROB_MAX];
blobmsg_parse(prob_policy, __PROB_MAX, tb, blob_data(msg), blob_len(msg));
if (hwaddr_aton(blobmsg_data(tb[PROB_BSSID_ADDR]), prob_req->bssid_addr))
@ -79,11 +126,20 @@ int parse_to_probe_req(struct blob_attr *msg, probe_entry *prob_req) {
if (tb[PROB_SIGNAL]) {
prob_req->signal = blobmsg_get_u32(tb[PROB_SIGNAL]);
}
else
{
return -1;
}
if (tb[PROB_FREQ]) {
prob_req->freq = blobmsg_get_u32(tb[PROB_FREQ]);
}
else
{
return -1;
}
return 0;
}
@ -184,24 +240,136 @@ int dawn_init_ubus(const char *ubus_socket, char *hostapd_dir) {
return 0;
}
static void
dump_client(struct blob_attr **tb, uint8_t client_addr[], const char* bssid_addr, uint32_t freq)
{
client client_entry;
hwaddr_aton(bssid_addr, client_entry.bssid_addr);
memcpy(client_entry.client_addr, client_addr, ETH_ALEN * sizeof(uint8_t));
char mac_buf_client[20];
char mac_buf_ap[20];
sprintf(mac_buf_ap, "%x:%x:%x:%x:%x:%x", MAC2STR(client_entry.bssid_addr));
sprintf(mac_buf_client, "%x:%x:%x:%x:%x:%x", MAC2STR(client_entry.client_addr));
client_entry.freq = freq;
if (tb[CLIENT_AUTH]) {
client_entry.auth = blobmsg_get_u8(tb[CLIENT_AUTH]);
}
if (tb[CLIENT_ASSOC]) {
client_entry.assoc = blobmsg_get_u8(tb[CLIENT_ASSOC]);
}
if(tb[CLIENT_AUTHORIZED])
{
client_entry.authorized = blobmsg_get_u8(tb[CLIENT_AUTHORIZED]);
}
if(tb[CLIENT_PREAUTH]){
client_entry.preauth = blobmsg_get_u8(tb[CLIENT_PREAUTH]);
}
if(tb[CLIENT_WDS]){
client_entry.wds = blobmsg_get_u8(tb[CLIENT_WDS]);
}
if(tb[CLIENT_WMM]){
client_entry.wmm = blobmsg_get_u8(tb[CLIENT_WMM]);
}
if(tb[CLIENT_HT]){
client_entry.ht = blobmsg_get_u8(tb[CLIENT_HT]);
}
if(tb[CLIENT_VHT]){
client_entry.vht = blobmsg_get_u8(tb[CLIENT_VHT]);
}
if(tb[CLIENT_WPS]){
client_entry.wps = blobmsg_get_u8(tb[CLIENT_WPS]);
}
if(tb[CLIENT_MFP]){
client_entry.mfp = blobmsg_get_u8(tb[CLIENT_MFP]);
}
if(tb[CLIENT_AID]){
client_entry.aid = blobmsg_get_u32(tb[CLIENT_AID]);
}
insert_client_to_array(client_entry);
}
static void
dump_client_table(struct blob_attr *head, int len, const char* bssid_addr, uint32_t freq)
{
struct blob_attr *attr;
struct blobmsg_hdr *hdr;
__blob_for_each_attr(attr, head, len) {
hdr = blob_data(attr);
struct blob_attr *tb[__CLIENT_MAX];
blobmsg_parse(client_policy, __CLIENT_MAX, tb, blobmsg_data(attr), blobmsg_len(attr));
//char* str = blobmsg_format_json_indent(attr, true, -1);
int tmp_int_mac[ETH_ALEN];
uint8_t tmp_mac[ETH_ALEN];
sscanf((char*)hdr->name, "%x:%x:%x:%x:%x:%x", STR2MAC(tmp_int_mac));
for(int i = 0; i < ETH_ALEN; ++i )
tmp_mac[i] = (uint8_t) tmp_int_mac[i];
dump_client(tb, tmp_mac, bssid_addr, freq);
}
}
int parse_to_clients(struct blob_attr *msg) {
struct blob_attr *tb[__CLIENT_TABLE_MAX];
blobmsg_parse(client_table_policy, __CLIENT_TABLE_MAX, tb, blob_data(msg), blob_len(msg));
if (tb[CLIENT_TABLE] && tb[CLIENT_TABLE_BSSID] && tb[CLIENT_TABLE_FREQ]) {
dump_client_table(blobmsg_data(tb[CLIENT_TABLE]), blobmsg_data_len(tb[CLIENT_TABLE]), blobmsg_data(tb[CLIENT_TABLE_BSSID]), blobmsg_get_u32(tb[CLIENT_TABLE_FREQ]));
}
return 0;
}
static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_attr *msg)
{
char *str;
if (!msg)
return;
str = blobmsg_format_json_indent(msg, true, -1);
printf("%s\n", str);
free(str);
parse_to_clients(msg);
char *str = blobmsg_format_json(msg, true);
send_string(str);
print_client_array();
// TODO SEND CLIENT VIA NETWORK!
}
static int ubus_get_clients() {
uint32_t id;
int ret = ubus_lookup_id(ctx, "hostapd.wlan0", &id);
if (ret)
return ret;
int timeout = 1;
int ubus_shit = ubus_invoke(ctx, id, "get_clients", NULL, ubus_get_clients_cb, NULL, timeout * 1000);
printf("Ubus Shit: %d", ubus_shit);
return ubus_shit;
DIR *dirp;
struct dirent *entry;
dirp = opendir(hostapd_dir_glob); // error handling?
while ((entry = readdir(dirp)) != NULL) {
if (entry->d_type == DT_SOCK) {
char hostapd_iface[256];
uint32_t id;
sprintf(hostapd_iface, "hostapd.%s", entry->d_name);
int ret = ubus_lookup_id(ctx, hostapd_iface, &id);
if(!ret)
{
int timeout = 1;
ubus_invoke(ctx, id, "get_clients", NULL, ubus_get_clients_cb, NULL, timeout * 1000);
}
}
}
return 0;
}
void *update_clients_thread(void *arg)
{
while (1){
sleep(TIME_THRESHOLD_CLIENT);
printf("[Thread] : Updating clients!\n");
ubus_get_clients();
}
return 0;
}