diff --git a/wireless/wifictld/src/data.h b/wireless/wifictld/src/data.h index 0842342..12c9038 100644 --- a/wireless/wifictld/src/data.h +++ b/wireless/wifictld/src/data.h @@ -10,13 +10,13 @@ struct wifi_client { struct avl_node avl; u8 addr[ETH_ALEN]; time_t time; - int try_probe; - int try_auth; + uint16_t try_probe; + uint16_t try_auth; bool connected; bool authed; - uint32_t freq_highest; - uint32_t signal_lowfreq; - uint32_t signal_highfreq; + uint16_t freq_highest; + uint16_t signal_lowfreq; + uint16_t signal_highfreq; }; #endif diff --git a/wireless/wifictld/src/include.h b/wireless/wifictld/src/include.h index 937cdb6..06d56b4 100644 --- a/wireless/wifictld/src/include.h +++ b/wireless/wifictld/src/include.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/wireless/wifictld/src/socket.c b/wireless/wifictld/src/socket.c index 210d320..8a670fb 100644 --- a/wireless/wifictld/src/socket.c +++ b/wireless/wifictld/src/socket.c @@ -1,8 +1,71 @@ #include "include.h" #include "log.h" #include "socket.h" +#include "socket_msg.h" static struct uloop_fd server; +struct in6_addr ownaddr; +struct sockaddr_in6 client_addr; + +int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer, struct timeval timeout) { + int ret = 0; + int sock = 0; + char msg[REQUEST_MAXLEN]; + request->type = (request->type | SOCKET_MSG_TYPE_REQUEST); + + ret = socket_msg_marshal(request, msg); + if (ret) { + log_error("socket_request: could not marshel message: %d\n", ret); + return ret; + } + + sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + log_error("socket_request: could not create socket\n"); + return -1; + } + + + int loop = 0; + if(setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) { + log_error("socket_request: unable to disable listen/loop own multicast package: %d\n", errno); + return -1; + } + + ret = sendto(sock, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&client_addr, sizeof(client_addr)); + if (ret < 0) { + close(sock); + log_error("socket_request: could not send message: %d\n", ret); + return ret; + } + + ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,sizeof(timeout)); + if(ret < 0) { + close(sock); + log_error("socket_request: unable to set timeout: %d\n", errno); + return ret; + } + ret = recv(sock, msg, REQUEST_MAXLEN, 0); + close(sock); + if (ret < 0) { + if(errno == EWOULDBLOCK) + return ret; + log_error("socket_request: could not recv message: %d\n", ret); + return ret; + } + + ret = socket_msg_unmarshal(answer, msg); + if (ret) { + log_error("socket_request: could not unmarshel message: %d\n", ret); + return ret; + } + + log_verbose("socket_request: end %d\n", ret); + if(answer->type & SOCKET_MSG_TYPE_RESPONSE) { + return -1; + } + return ret; +} static void server_cb(struct uloop_fd *fd, unsigned int events) { struct sockaddr_in6 addr; @@ -46,28 +109,34 @@ int socket_init(char *ifname) { if (server.fd < 0) { return 1; } - struct in6_addr mgroup_addr; - if (!inet_pton(AF_INET6, SOCKET_MADDR, &mgroup_addr)) { + client_addr.sin6_family = AF_INET6; + client_addr.sin6_port = htons(atoi(SOCKET_PORT)); + client_addr.sin6_scope_id = if_nametoindex(ifname); + + // listen multicast + if (!inet_pton(AF_INET6, SOCKET_MADDR, &client_addr.sin6_addr)) { log_error("socket: invalid multicast group\n"); return -1; } - struct ipv6_mreq mreq; - - mreq.ipv6mr_multiaddr = mgroup_addr; - mreq.ipv6mr_interface = if_nametoindex(ifname); + struct ipv6_mreq mreq = { + .ipv6mr_multiaddr = client_addr.sin6_addr, + .ipv6mr_interface = client_addr.sin6_scope_id, + }; if (setsockopt(server.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1) { - log_error("socket: unable to join multicast group\n"); + log_error("socket: unable to join multicast group: %d\n", errno); return -1; } - + // end listen multicast uloop_fd_add(&server, ULOOP_READ); return 0; } void socket_close() { - + uloop_fd_delete(&server); + //ustream_free(&(server.fd)); + close(server.fd); } diff --git a/wireless/wifictld/src/socket.h b/wireless/wifictld/src/socket.h index ff1c752..898b544 100644 --- a/wireless/wifictld/src/socket.h +++ b/wireless/wifictld/src/socket.h @@ -1,13 +1,25 @@ #ifndef __WIFICTLD_SOCKET_H #define __WIFICTLD_SOCKET_H +#include "include.h" +#include "socket_msg.h" + #define SOCKET_ADDR "::" #define SOCKET_MADDR "ff02::31f1" #define SOCKET_PORT "1000" -#define REQUEST_MAXLEN 256 - int socket_init(); void socket_close(); +int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer, struct timeval timeout); + +static inline int socket_request(struct socket_msg *request, struct socket_msg *answer) +{ + struct timeval tv = { + .tv_sec = 0, + .tv_usec = 100000, + }; + return socket_request_timeout(request, answer, tv); +} + #endif diff --git a/wireless/wifictld/src/socket_msg.c b/wireless/wifictld/src/socket_msg.c new file mode 100644 index 0000000..db4fc48 --- /dev/null +++ b/wireless/wifictld/src/socket_msg.c @@ -0,0 +1,100 @@ +#include "include.h" +#include "socket_msg.h" + + +int socket_msg_marshal(struct socket_msg *src, char dest[REQUEST_MAXLEN]) { + uint32_t nl = 0; + uint16_t ns = 0; + int pos = 0; + + memset(dest, 0, REQUEST_MAXLEN); + + nl = htonl(src->type); + memcpy(dest + pos, &nl, sizeof(nl)); + pos += sizeof(nl); + + if (src->type & SOCKET_MSG_TYPE_CLIENT) { + memcpy(dest + pos, src->client->addr, sizeof(src->client->addr)); + pos += sizeof(src->client->addr); + + nl = htonl(src->client->time); + memcpy(dest + pos, &nl, sizeof(nl)); + pos += sizeof(nl); + + ns = htons(src->client->try_probe); + memcpy(dest + pos, &ns, sizeof(ns)); + pos += sizeof(ns); + + ns = htons(src->client->try_auth); + memcpy(dest + pos, &ns, sizeof(ns)); + pos += sizeof(ns); + + memcpy(dest + pos, &src->client->connected, sizeof(src->client->connected)); + pos += sizeof(src->client->connected); + + memcpy(dest + pos, &src->client->authed, sizeof(src->client->authed)); + pos += sizeof(src->client->authed); + + ns = htons(src->client->freq_highest); + memcpy(dest + pos, &ns, sizeof(ns)); + pos += sizeof(ns); + + ns = htons(src->client->signal_lowfreq); + memcpy(dest + pos, &ns, sizeof(ns)); + pos += sizeof(ns); + + ns = htons(src->client->signal_highfreq); + memcpy(dest + pos, &ns, sizeof(ns)); + pos += sizeof(ns); + + } + memset(dest + pos, 0, REQUEST_MAXLEN-pos); + + return 0; +} + +int socket_msg_unmarshal(struct socket_msg *dest, char src[REQUEST_MAXLEN]) { + uint32_t nl = 0; + uint16_t ns = 0; + int pos = 0; + + memcpy(&nl, src + pos, sizeof(nl)); + pos += sizeof(nl); + dest->type = ntohl(nl); + + if (dest->type & SOCKET_MSG_TYPE_CLIENT) { + memcpy(dest->client->addr, src + pos, sizeof(dest->client->addr)); + pos += sizeof(dest->client->addr); + + memcpy(&nl, src + pos, sizeof(nl)); + pos += sizeof(nl); + dest->client->time = ntohl(nl); + + memcpy(&ns, src + pos, sizeof(ns)); + pos += sizeof(ns); + dest->client->try_probe = ntohs(ns); + + memcpy(&ns, src + pos, sizeof(ns)); + pos += sizeof(ns); + dest->client->try_auth = ntohs(ns); + + memcpy(&dest->client->connected, src + pos, sizeof(dest->client->connected)); + pos += sizeof(dest->client->connected); + + memcpy(&dest->client->authed, src + pos, sizeof(dest->client->authed)); + pos += sizeof(dest->client->authed); + + memcpy(&ns, src + pos, sizeof(ns)); + pos += sizeof(ns); + dest->client->freq_highest = ntohs(ns); + + memcpy(&ns, src + pos, sizeof(ns)); + pos += sizeof(ns); + dest->client->signal_lowfreq = ntohs(ns); + + memcpy(&ns, src + pos, sizeof(ns)); + pos += sizeof(ns); + dest->client->signal_highfreq = ntohs(ns); + } + return 0; +} diff --git a/wireless/wifictld/src/socket_msg.h b/wireless/wifictld/src/socket_msg.h new file mode 100644 index 0000000..fac9804 --- /dev/null +++ b/wireless/wifictld/src/socket_msg.h @@ -0,0 +1,24 @@ +#ifndef __WIFICTLD_SOCKET_MSG_H +#define __WIFICTLD_SOCKET_MSG_H + +#include "include.h" +#include "data.h" + +#define REQUEST_MAXLEN 256 + +enum socket_msg_type { + SOCKET_MSG_TYPE_REQUEST = (1 << 0), + SOCKET_MSG_TYPE_RESPONSE = (1 << 1), + SOCKET_MSG_TYPE_CLIENT = (1 << 2), + SOCKET_MSG_TYPE_STATS = (1 << 3), +}; + +struct socket_msg { + uint32_t type; + struct wifi_client *client; +}; + +int socket_msg_marshal(struct socket_msg *src, char dest[REQUEST_MAXLEN]); +int socket_msg_unmarshal(struct socket_msg *dest, char src[REQUEST_MAXLEN]); + +#endif diff --git a/wireless/wifictld/src/ubus_events.c b/wireless/wifictld/src/ubus_events.c index 886ad84..f4c354c 100644 --- a/wireless/wifictld/src/ubus_events.c +++ b/wireless/wifictld/src/ubus_events.c @@ -142,20 +142,20 @@ static int receive_notify(struct ubus_context *ctx, struct ubus_object *obj, str if (!strcmp(method, "auth")) { hclient.auth = true; if (wifi_clients_try(&hclient)) { - log_debug(" -> reject\n"); + log_verbose(" -> reject\n"); return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; } - log_debug(" -> accept\n"); + log_verbose(" -> accept\n"); return WLAN_STATUS_SUCCESS; } if (!strcmp(method, "probe")) { if(config_client_probe_steering) { if (wifi_clients_try(&hclient)) { - log_debug(" -> reject\n"); + log_verbose(" -> reject\n"); return WLAN_STATUS_UNSPECIFIED_FAILURE; } - log_debug(" -> accept\n"); + log_verbose(" -> accept\n"); return WLAN_STATUS_SUCCESS; } if(config_client_probe_learning) { diff --git a/wireless/wifictld/src/wifi_clients.c b/wireless/wifictld/src/wifi_clients.c index 9f57efc..8a81a5f 100644 --- a/wireless/wifictld/src/wifi_clients.c +++ b/wireless/wifictld/src/wifi_clients.c @@ -3,6 +3,9 @@ #include "log.h" #include "data.h" #include "wifi_clients.h" +#ifndef MINI +#include "socket.h" +#endif void clean_cbhandler(struct uloop_timeout *t) @@ -100,6 +103,16 @@ struct wifi_client *__get_client(struct hostapd_client *hclient){ client->authed = false; client->freq_highest = 0; __client_setvalues(client, hclient); + #ifndef MINI + struct socket_msg req = { + .type = SOCKET_MSG_TYPE_CLIENT, + .client = client, + }, resp; + if(socket_request(&req, &resp) == 0){ + log_debug("wifi_clients.__get_client("MACSTR"): get client from neigbour\n", MAC2STR(hclient->address)); + return resp.client; + } + #endif client->avl.key = client->addr; log_debug("wifi_clients.__get_client("MACSTR"): add client to mem\n", MAC2STR(hclient->address)); avl_insert(&clients_by_addr, &client->avl);