diff --git a/include/wifi_events.h b/include/wifi_events.h index 16c7ea5d7..54c507b94 100644 --- a/include/wifi_events.h +++ b/include/wifi_events.h @@ -135,6 +135,7 @@ typedef enum { wifi_event_type_dfs_atbootup_rfc, wifi_event_type_command_kickmac, wifi_event_type_command_kick_assoc_devices, + wifi_event_type_command_frame_drop_unenc, wifi_event_type_command_wps, wifi_event_type_command_wps_pin, wifi_event_type_command_wps_cancel, diff --git a/source/core/wifi_ctrl_queue_handlers.c b/source/core/wifi_ctrl_queue_handlers.c index 026c7bd8c..1ffdd74e2 100644 --- a/source/core/wifi_ctrl_queue_handlers.c +++ b/source/core/wifi_ctrl_queue_handlers.c @@ -1521,6 +1521,26 @@ void kick_all_macs(int vap_index, int timeout, rdk_wifi_vap_info_t *rdk_vap_info } } +void process_frame_drop_unenc_command_event(void *data) +{ + assoc_dev_data_t *req; + mac_addr_str_t mac_str; + + if (data == NULL) { + wifi_util_error_print(WIFI_CTRL, "%s:%d NULL data\n", __func__, __LINE__); + return; + } + + req = (assoc_dev_data_t *)data; + to_mac_str(req->dev_stats.cli_MACAddress, mac_str); + + wifi_util_info_print(WIFI_CTRL, + "%s:%d: [FC_WEP] disassociating client %s on ap:%d reason=%d\n", + __func__, __LINE__, mac_str, req->ap_index, req->reason); + + wifi_hal_disassoc(req->ap_index, req->reason, req->dev_stats.cli_MACAddress); +} + void process_kick_assoc_devices_event(void *data) { wifi_util_dbg_print(WIFI_CTRL, "%s:%d Entry\n", __func__, __LINE__); @@ -4386,6 +4406,10 @@ void handle_command_event(wifi_ctrl_t *ctrl, void *data, unsigned int len, process_kick_assoc_devices_event(data); break; + case wifi_event_type_command_frame_drop_unenc: + process_frame_drop_unenc_command_event(data); + break; + case wifi_event_type_command_wps: process_wps_command_event(*(unsigned int *)data); break; diff --git a/source/core/wifi_events.c b/source/core/wifi_events.c index 530bdc547..a2b3544a6 100644 --- a/source/core/wifi_events.c +++ b/source/core/wifi_events.c @@ -125,6 +125,7 @@ const char *wifi_event_subtype_to_string(wifi_event_subtype_t type) DOC2S(wifi_event_type_dfs_atbootup_rfc) DOC2S(wifi_event_type_command_kickmac) DOC2S(wifi_event_type_command_kick_assoc_devices) + DOC2S(wifi_event_type_command_frame_drop_unenc) DOC2S(wifi_event_type_command_wps) DOC2S(wifi_event_type_command_wps_pin) DOC2S(wifi_event_type_command_wps_cancel) @@ -218,6 +219,7 @@ bool is_high_priority_event(wifi_event_subtype_t sub_type) switch (sub_type) { case wifi_event_type_notify_monitor_done: case wifi_event_type_command_factory_reset: + case wifi_event_type_command_frame_drop_unenc: case wifi_event_type_eth_bh_status: case wifi_event_type_xfinity_enable: case wifi_event_type_prefer_private_rfc: diff --git a/source/stats/wifi_monitor.c b/source/stats/wifi_monitor.c index 173e876e8..b3494b797 100644 --- a/source/stats/wifi_monitor.c +++ b/source/stats/wifi_monitor.c @@ -28,6 +28,7 @@ #include #include "collection.h" #include "wifi_hal.h" +#include "wifi_hal_rdk_framework.h" #include "wifi_mgr.h" #include "wifi_stubs.h" #include "wifi_util.h" @@ -3992,6 +3993,59 @@ int device_disassociated(int ap_index, char *src_mac, char *dest_mac, int type, return 0; } +int device_frame_drop_unencrypted(int ap_index, char *src_mac, unsigned short ether_type) +{ + mac_address_t sta_mac; + assoc_dev_data_t assoc_data; + char cli_ip_str[IP_STR_LEN] = { 0 }; + char cli_interface_str[IFNAMSIZ] = { 0 }; + const int reason = WLAN_REASON_PREV_AUTH_NOT_VALID; + + if (src_mac == NULL) { + wifi_util_dbg_print(WIFI_MON, "%s:%d input mac is NULL for ap_index:%d\n", + __func__, __LINE__, ap_index); + return RETURN_ERR; + } + + if (active_sta_connection_status(ap_index, src_mac) == false) { + wifi_util_dbg_print(WIFI_MON, + "%s:%d: [FC_WEP] client[%s] not active on ap:%d - ignoring\n", + __func__, __LINE__, src_mac, ap_index); + return RETURN_OK; + } + + str_to_mac_bytes(src_mac, sta_mac); + + /* Only force a disassoc when the STA has no IPv4 yet, where the + * unprotected frames are blocking DHCP from ever succeeding. */ + if (csi_getClientIpAddress(src_mac, cli_ip_str, cli_interface_str, 1) == 0 && + cli_ip_str[0] != '\0') { + wifi_util_dbg_print(WIFI_MON, + "%s:%d: [FC_WEP] client[%s] has IPv4 %s on %s - no action\n", + __func__, __LINE__, src_mac, cli_ip_str, cli_interface_str); + return RETURN_OK; + } + + wifi_util_info_print(WIFI_MON, + "%s:%d: [FC_WEP] client[%s] on ap:%d (ethertype:0x%04x) has no IPv4 - " + "queueing disassoc\n", + __func__, __LINE__, src_mac, ap_index, ether_type); + + memset(&assoc_data, 0, sizeof(assoc_data)); + assoc_data.ap_index = ap_index; + assoc_data.reason = reason; + memcpy(assoc_data.dev_stats.cli_MACAddress, sta_mac, sizeof(mac_address_t)); + if (push_event_to_ctrl_queue(&assoc_data, sizeof(assoc_data), + wifi_event_type_command, wifi_event_type_command_frame_drop_unenc, NULL) != RETURN_OK) { + wifi_util_error_print(WIFI_MON, + "%s:%d: [FC_WEP] failed to queue disassoc for client[%s] on ap:%d\n", + __func__, __LINE__, src_mac, ap_index); + return RETURN_ERR; + } + + return RETURN_OK; +} + void notify_radius_endpoint_change(radius_fallback_and_failover_data_t *radius_data) { wifi_vap_security_t *vapSecurity = (wifi_vap_security_t *)Get_wifi_object_bss_security_parameter(radius_data->apIndex); @@ -4755,6 +4809,7 @@ int init_wifi_monitor() wifi_vapstatus_callback_register(vapstatus_callback); wifi_hal_apDeAuthEvent_callback_register(device_deauthenticated); wifi_hal_apDisassociatedDevice_callback_register(device_disassociated); + wifi_hal_apFrameDropUnencrypted_callback_register(device_frame_drop_unencrypted); wifi_hal_ap_max_client_rejection_callback_register(device_max_client_rejection); wifi_hal_radius_eap_failure_callback_register(radius_eap_failure_callback); wifi_hal_radiusFallback_failover_callback_register(radius_fallback_and_failover_callback);