diff --git a/src/binding/ieee80211/wifi_nl80211.c b/src/binding/ieee80211/wifi_nl80211.c index bd99df7..701a761 100644 --- a/src/binding/ieee80211/wifi_nl80211.c +++ b/src/binding/ieee80211/wifi_nl80211.c @@ -317,6 +317,7 @@ static void nl80211_do_mgmt_probe_request_event(struct nl80211_wlan_handle* wlan /* */ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wlanhandle, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) { + int acl; int ielength; struct ieee80211_ie_items ieitems; int responselength; @@ -327,6 +328,17 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla struct ieee80211_authentication_params ieee80211_params; struct wlan_send_frame_params wlan_params; + /* Ignore authentication packet from same AP */ + if (!memcmp(mgmt->sa, wlanhandle->address, ETH_ALEN)) { + return; + } + + /* Get ACL Station */ + acl = wtp_radio_acl_station(mgmt->sa); + if (acl == WTP_RADIO_ACL_STATION_DENY) { + return; + } + /* Information Elements packet length */ ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication)); if (ielength < 0) { @@ -338,14 +350,6 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla return; } - /* Ignore authentication packet from same AP */ - if (!memcmp(mgmt->sa, wlanhandle->address, ETH_ALEN)) { - return; - } - - /* ACL Station */ - /* TODO */ - /* Create station reference */ /* TODO */ diff --git a/src/wtp/wtp.h b/src/wtp/wtp.h index 3c9808e..0afea97 100644 --- a/src/wtp/wtp.h +++ b/src/wtp/wtp.h @@ -140,6 +140,10 @@ struct wtp_t { struct wifi_event* events; int eventscount; + /* Radio ACL */ + int defaultaclstations; + struct capwap_hash* aclstations; + /* Dtls */ int enabledtls; unsigned char dtlsdatapolicy; diff --git a/src/wtp/wtp_radio.c b/src/wtp/wtp_radio.c index d2f4438..d9619e6 100644 --- a/src/wtp/wtp_radio.c +++ b/src/wtp/wtp_radio.c @@ -1,4 +1,5 @@ #include "wtp.h" +#include "capwap_hash.h" #include "wtp_radio.h" /* */ @@ -48,9 +49,21 @@ static void wtp_radio_destroy_wlan(struct wtp_radio_wlan* wlan) { memset(wlan, 0, sizeof(struct wtp_radio_wlan)); } +/* */ +unsigned long wtp_radio_acl_item_gethash(const void* key, unsigned long keysize, unsigned long hashsize) { + uint8_t* macaddress = (uint8_t*)key; + + ASSERT(keysize == ETH_ALEN); + + return ((macaddress[3] ^ macaddress[4] ^ macaddress[5]) >> 2); +} + /* */ void wtp_radio_init(void) { g_wtp.radios = capwap_array_create(sizeof(struct wtp_radio), 0, 1); + + g_wtp.defaultaclstations = WTP_RADIO_ACL_STATION_ALLOW; + g_wtp.aclstations = capwap_hash_create(WTP_RADIO_ACL_HASH_SIZE, WTP_RADIO_ACL_KEY_SIZE, wtp_radio_acl_item_gethash, NULL, NULL); } /* */ @@ -88,6 +101,7 @@ void wtp_radio_free(void) { } capwap_array_free(g_wtp.radios); + capwap_hash_free(g_wtp.aclstations); } /* */ @@ -560,3 +574,29 @@ uint32_t wtp_radio_delete_wlan(struct capwap_parsed_packet* packet) { /* TODO */ return CAPWAP_RESULTCODE_SUCCESS; } + +/* */ +int wtp_radio_acl_station(const uint8_t* macaddress) { + ASSERT(macaddress != NULL); + + /* Check if exist ACL for station */ + if (capwap_hash_hasitem(g_wtp.aclstations, macaddress)) { + return ((g_wtp.defaultaclstations == WTP_RADIO_ACL_STATION_ALLOW) ? WTP_RADIO_ACL_STATION_DENY : WTP_RADIO_ACL_STATION_ALLOW); + } + + /* Default ACL station */ + return g_wtp.defaultaclstations; +} + +/* */ +void wtp_radio_acl_addstation(const uint8_t* macaddress) { + ASSERT(macaddress != NULL); + + capwap_hash_add(g_wtp.aclstations, macaddress, NULL); +} + +void wtp_radio_acl_deletestation(const uint8_t* macaddress) { + ASSERT(macaddress != NULL); + + capwap_hash_delete(g_wtp.aclstations, macaddress); +} diff --git a/src/wtp/wtp_radio.h b/src/wtp/wtp_radio.h index cbcf1ef..a280e51 100644 --- a/src/wtp/wtp_radio.h +++ b/src/wtp/wtp_radio.h @@ -9,6 +9,13 @@ #define WTP_RADIO_HWFAILURE 2 #define WTP_RADIO_SWFAILURE 3 +/* */ +#define WTP_RADIO_ACL_HASH_SIZE 64 +#define WTP_RADIO_ACL_KEY_SIZE ETH_ALEN + +#define WTP_RADIO_ACL_STATION_ALLOW 0 +#define WTP_RADIO_ACL_STATION_DENY 1 + /* */ #define WTP_PREFIX_NAME_MAX_LENGTH (IFNAMSIZ - 6) #define WTP_PREFIX_DEFAULT_NAME "ap" @@ -76,4 +83,9 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwa uint32_t wtp_radio_update_wlan(struct capwap_parsed_packet* packet); uint32_t wtp_radio_delete_wlan(struct capwap_parsed_packet* packet); +/* Station ACL */ +int wtp_radio_acl_station(const uint8_t* macaddress); +void wtp_radio_acl_addstation(const uint8_t* macaddress); +void wtp_radio_acl_deletestation(const uint8_t* macaddress); + #endif /* __WTP_RADIO_HEADER__ */