#define DEBUG_INTERVAL 5000 // 每5秒打印一次表项统计
static u_int32_t last_debug_time = 0; // 全局/静态变量记录上次打印时间
static int study_flag = 0;
static uint study_item_time = 0;
static int study_shot_count = 0;
static int study_item_num = 0;
static int skip_next_cycle = 0; // 暂停标志
static int wids_wips_detect_flood(wlc_info_t *wlc, wlc_d11rxhdr_t *wrxh, struct dot11_management_header *hdr)
{
u_int32_t *mac_key = NULL;
int hash_key = 0;
ieee80211_wids_wips_hash_table *hash = NULL;
wids_wips_param *param = wids_wips_param_get();
wids_wips_priv_node *node = NULL;
wids_wips_priv_node *dyNode = NULL;
ieee80211_wids_wips_hash_table *dyHash = NULL;
uint addTime = 0;
ath_wids_wips_msg_t eventMsg;
struct timeval sysTime;
uint16 fc;
int32_t subtype;
if(0 == widswips_init){
return WIDS_WIPS_OK;
}
if (NULL == hdr || NULL == wlc || NULL == wrxh)
{
return WIDS_WIPS_OK;
}
if (WIDS_WIPS_EVENT_ENABLE != param->ic_cfg.enableBit.is_enable_detect_client_flood)
{
return WIDS_WIPS_OK;
}
// 小端序:刚开始(低地址)存储的是低位字节
mac_key = (u_int32_t *)(&hdr->sa.octet[2]);
hash_key = WIDS_WIPS_NODE_HASH(*mac_key, WIDS_WIPS_NODE_HASH_KEY);
hash = &(param->ic_flood_hash[hash_key]);
spin_lock_dpc(¶m->ic_wids_wips_lock);
node = wids_wips_priv_node_lookup(hash, (u_int8_t *)(hdr->sa.octet));
fc = ltoh16(hdr->fc);
subtype = FC_SUBTYPE(fc);
addTime = OSL_SYSUPTIME();
if (addTime - last_debug_time > DEBUG_INTERVAL) {
int flood_table_cnt = 0;
for (int index = 0; index < WIDS_WIPS_NODE_TABLE_LEN; index++)
{
if (NODE_STATE_ACTIVE == param->ic_flood_table.node[index].ni_elem.state){
flood_table_cnt++;
}
}
WIDSWIPS_DEBUG("[DEBUG] flood_table_cntm=%d,flood_table_cnt", flood_table_cnt);
// wf_chspec_primary20_chan(wlc->chanspec), wrxh->rssi
WIDSWIPS_DEBUG("[DEBUG] flood_table channl=%d,wrxh->rssi = %d", wf_chspec_primary20_chan(wlc->chanspec), wrxh->rssi);
last_debug_time = addTime;
}
if (NULL == node) {
if (skip_next_cycle) {
if (addTime - study_item_time > WIDS_WIPS_STUDY_TIME) {
// 暂停周期结束,恢复正常计数
skip_next_cycle = 0;
study_item_time = addTime; // 重置时间窗口
}
// 暂停期间直接跳过所有操作
return WIDS_WIPS_OK;
}
if (addTime - study_item_time > WIDS_WIPS_STUDY_TIME) {
WIDSWIPS_DEBUG("study_ study_shot_count = %d, study_item_num = %d", study_shot_count, study_item_num);
// 时间窗口到期,进行阈值判断
if (study_item_num > WIDS_WIPS_STUDY_ITEM_COUNT &&
(study_shot_count * 10 > study_item_num * 8)) {
// 触发学习模式:缩短黑名单老化时间
WIDSWIPS_DEBUG("study_shot_count");
study_flag = 1;
param->ic_cfg.dy_black_list_expire_time = 300;
skip_next_cycle = 1; // 标记下一个周期暂停
} else {
// 未达阈值:恢复默认老化时间
WIDSWIPS_DEBUG("study_shot_count no");
study_flag = 0;
param->ic_cfg.dy_black_list_expire_time = param->black_list_expire_time_backup;
}
study_item_time = addTime; // 重置时间窗口
study_item_num = 0; // 重置计数器
study_shot_count = 0;
}
else{
wids_wips_priv_node *study_node = NULL;
// 查看是否命中
for (int index = 0; index < WIDS_WIPS_NODE_TABLE_LEN; index++)
{
study_node = &(param->ic_flood_table.node[index].ni_elem);
if (NODE_STATE_ACTIVE == study_node->state){
if ((0 == memcmp(study_node->sourceMac, (u_int8_t *)(hdr->sa.octet), 3))
&& (abs(study_node->sourceApRssi - wrxh->rssi) < 4)
&& study_node->bss_chann.ic_freq == wf_chspec_primary20_chan(wlc->chanspec)) /* find the entry */
{
study_shot_count ++;
break;
}
}
}
study_item_num++;
}
}
// else {
// // 时间窗口内:记录新表项
// // TODO: 是否是小端序
// u_int16_t* study_mac_key = (u_int16_t*)(hdr->sa.octet);//
// uint32_t study_hash_key = WIDS_WIPS_NODE_HASH(*study_mac_key, WIDS_WIPS_NODE_HASH_KEY);
// ieee80211_wids_wips_hash_table* study_hash = ¶m->ic_flood_hash[study_hash_key];
// // 查找OUI表项
// wids_wips_priv_node* oui_node =
// wids_wips_priv_node_lookup(study_hash, (u_int8_t *)(hdr->sa.octet));
// // wids_wips_priv_node_lookup_studyitem(study_hash, hdr->sa.octet,
// // wf_chspec_primary20_chan(wlc->chanspec), wrxh->rssi);
// // wf_chspec_primary20_chan(wlc->chanspec)
// // rssi
// if (NULL == oui_node) {
// u_int8_t ouiMac[IEEE80211_ADDR_LEN] = {0};
// memcpy(ouiMac, hdr->sa.octet, 3);
// struct ieee80211_ath_channel ath_chan = {0};
// ath_chan.ic_freq = wf_chspec_primary20_chan(wlc->chanspec);
// // 添加新OUI表项
// oui_node = wids_wips_node_alloc_studyitem(¶m->ic_flood_table, NODE_STATE_ACTIVE,
// ouiMac, 0, ath_chan, wrxh->rssi, 0, addTime, 0, 0);
// if (oui_node) {
// wids_wips_priv_node_add(study_hash, oui_node);
// param->study_item_num++; // 新增表项计数
// }
// } else {
// // 表项已存在:增加触发计数
// param->study_shot_count++;
// }
// }
// }
// ===== 结束新增逻辑 =====
if (NULL == node)
{
/* alloc new node */
addTime = OSL_SYSUPTIME();
struct ieee80211_ath_channel ath_chan = {0};
ath_chan.ic_freq = wf_chspec_primary20_chan(wlc->chanspec);
node = wids_wips_node_alloc(&(param->ic_flood_table), NODE_STATE_ACTIVE, (u_int8_t *)(hdr->sa.octet),
subtype, ath_chan, wrxh->rssi, 0, addTime, 0, 0);
if (NULL == node) /* no enough node */
{
spin_unlock_dpc(¶m->ic_wids_wips_lock);
// WIDSWIPS_DEBUG("No enough memory for a new node (1), realease someNode!");
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
_wids_wips_release_timeout_node((unsigned long)(l_widswips_param_p));
#else
_wids_wips_release_timeout_node(&(l_widswips_param_p->wids_wips_timer));
#endif
return WIDS_WIPS_OK;
}
/* add to hash table */
wids_wips_priv_node_add(hash, node);
}
else
{
// if (0 == bcmp(hdr->sa.octet, TARGET_MAC, IEEE80211_ADDR_LEN) && (node->count % 100 == 0)){
// WIDSWIPS_DEBUG("run to detect_flood node->count = %d fc = %d mac_key = %u" , node->count, fc, *mac_key);
// WIDSWIPS_DEBUG("hash_key = %d OSL_SYSUPTIME() = %u node->addTime = %ld", hash_key, OSL_SYSUPTIME(), node->addTime);
// }
/* 比较当前时间与加入时间的差值是否大于阈值 */
if (CONVERT_SYSTEM_TIME_TO_SEC(OSL_SYSUPTIME() - node->addTime) < WIDS_WIPS_FLOOD_DETECT_TIME)
{
// if (0 == bcmp(hdr->sa.octet, TARGET_MAC, IEEE80211_ADDR_LEN) && (node->count < 50 || node->count > 1400)){
// WIDSWIPS_DEBUG("fc = %d fc & FC_NULL_DATA = %d FC_TYPE(fc) = %d" , fc, FC_NULL_DATA, FC_TYPE(fc));
// // WIDSWIPS_DEBUG("hash_key = %d OSL_SYSUPTIME() = %u node->addTime = %ld", hash_key, OSL_SYSUPTIME(), node->addTime);
// }
// FC_NULL_DATA 0100 10 probe_req 0100 00
// 子类型可能一样, 导致出现问题, 表示数据包类型为数据 表示子类型为无数据。
if ((FC_TYPE(fc) == FC_TYPE_DATA) && (fc & FC_NULL_DATA))
{
node->nullCount += 1;
}
// 表示数据包类型为管理。FC_TYPE_MNG 0
else if (FC_TYPE(fc) == FC_TYPE_MNG)
{
node->count += 1;
}
}
else
{
/* 比较失败次数是否大于阈值 */
if ((node->count > WIDS_WIPS_FLOOD_MAX_COUNT) || (node->nullCount > WIDS_WIPS_FLOOD_MAX_COUNT))
{
/* 加入动态黑名单, 动态黑名单需要记录当前的 sysTime */
/* 需要controller打开动态黑名单功能,否则关开该功能后会在controller出现同一mac的大量条目 */
if (param->ic_cfg.isBlackEn)
{
addTime = OSL_SYSUPTIME();
memset(&sysTime, 0, sizeof(sysTime));
do_gettimeofday(&sysTime);
dyHash = &(param->ic_dyblacklist_hash[hash_key]);
dyNode = wids_wips_node_alloc(&(param->ic_dyblacklist_table), NODE_STATE_ACTIVE, (u_int8_t *)node->sourceMac,
0, node->bss_chann, 0, 0, addTime, sysTime.tv_sec, 0);
if (NULL == dyNode) /* no enough node */
{
spin_unlock_dpc(¶m->ic_wids_wips_lock);
WIDSWIPS_DEBUG("No enough memory for a new node (2)!");
return WIDS_WIPS_OK;
}
wids_wips_priv_node_add(dyHash, dyNode);
wids_wips_notify_black_list(); /* 有动态黑名单节点被添加,通知用户态 */
WIDSWIPS_DEBUG("Add device %2x:%2x:%2x:%2x:%2x:%2x to dynamic black list!", dyNode->sourceMac[0], dyNode->sourceMac[1],
dyNode->sourceMac[2], dyNode->sourceMac[3],
dyNode->sourceMac[4], dyNode->sourceMac[5]);
}
if (node->nullCount > WIDS_WIPS_FLOOD_MAX_COUNT)
{
WIDSWIPS_DEBUG("EVENT_POWER_SAVE_DOS_FLOOD");
memset(&eventMsg, 0, sizeof(ath_wids_wips_msg_t));
eventMsg.type = NETLINK_EVENT;
eventMsg.data.event.type = EVENT_POWER_SAVE_DOS_FLOOD;
memcpy(eventMsg.data.event.bssid, node->sourceMac, IEEE80211_ADDR_LEN);
memcpy(eventMsg.data.event.mac, node->sourceMac, IEEE80211_ADDR_LEN);
eventMsg.data.event.channel = wf_chspec_primary20_chan(wlc->chanspec);
eventMsg.data.event.flags = wl_chanspec_to_channel_flags(wlc);
ath_wids_wips_netlink_send(&eventMsg);
}
else if (node->count > WIDS_WIPS_FLOOD_MAX_COUNT)
{
WIDSWIPS_DEBUG("EVENT_CLIENT_FLOOD");
memset(&eventMsg, 0, sizeof(ath_wids_wips_msg_t));
eventMsg.type = NETLINK_EVENT;
eventMsg.data.event.type = EVENT_CLIENT_FLOOD;
memcpy(eventMsg.data.event.bssid, node->sourceMac, IEEE80211_ADDR_LEN);
memcpy(eventMsg.data.event.mac, node->sourceMac, IEEE80211_ADDR_LEN);
eventMsg.data.event.channel = wf_chspec_primary20_chan(wlc->chanspec);
eventMsg.data.event.flags = wl_chanspec_to_channel_flags(wlc);
ath_wids_wips_netlink_send(&eventMsg);
}
/* 移出flood table */
node->state = NODE_STATE_FREE;
memset(&node->sourceMac, 0, IEEE80211_ADDR_LEN);
node->addTime = 0;
wids_wips_priv_node_del(node);
}
else
{
/* 超时但未超出阈值,重新设置计数 */
node->addTime = OSL_SYSUPTIME();
node->count = 1;
}
}
}
spin_unlock_dpc(¶m->ic_wids_wips_lock);
return WIDS_WIPS_OK;
}这段函数完整的代码如上,请你分析
最新发布