run time dynamic node

本文介绍了一个月前完成的工具,其功能与realtimedynamicsetuptool类似,主要用于个人兴趣研究,未计划开源。该工具旨在提供一种新的实时动态设置方案。

大概一个月前我就写好了,但一直没时间整理,这个节点和我以前写的real time dynamic setup tool 工具功能类似,因为是写来玩的,所以没什么新功能,也不打算发布源代码。

#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(&param->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 = &param->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(&param->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(&param->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(&param->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(&param->ic_wids_wips_lock); return WIDS_WIPS_OK; }这段函数完整的代码如上,请你分析
最新发布
11-10
<think>首先,用户提供了完整的函数代码,并要求我分析它。函数名为 `wids_wips_detect_flood`,属于无线入侵检测系统(WIDS)或无线入侵防护系统(WIPS)的一部分。主要目的是检测网络中的泛洪攻击(flooding attacks)。 ### 函数功能概述: 1. **上下文检查**:确保模块已初始化,输入参数有效,并且泛洪检测功能已启用。 2. **哈希表查找**:基于源MAC地址在哈希表中查找节点。 3. **调试日志**:每5秒打印一次活动表项统计信息。 4. **学习模式逻辑**:处理暂停周期和学习模式,动态调整老化时间。 5. **节点创建**:如果节点不存在,则创建新节点并加入哈希表。 6. **计数更新**:如果节点存在,则根据帧类型更新计数(管理帧或空数据帧)。 7. **攻击检测**:如果计数超过阈值,则触发事件(如加入动态黑名单、发送通知)。 ### 详细代码分析: - **初始化检查**:检查全局初始化标志、输入参数、功能是否启用。 - **MAC地址处理**:提取源MAC地址的低位字节作为哈希键。 - **调试输出**:每5秒输出活动节点数量、信道和RSSI值。 - **学习模式逻辑**: - `skip_next_cycle` 用于暂停检测。 - 在时间窗口(`WIDS_WIPS_STUDY_TIME`)内,统计匹配特定条件的节点(OUI前3字节匹配、RSSI差值小、信道相同)。 - 窗口结束后,如果满足条件(表项数量和命中率),则进入学习模式(缩短黑名单老化时间),否则恢复默认值。 - **节点创建**:如果节点不存在,分配新节点并加入哈希表。如果分配失败,尝试释放超时节点。 - **计数更新**: - 对于数据帧中的空数据帧(Null Data),增加 `nullCount`。 - 对于管理帧(Management Frames),增加 `count`。 - **攻击检测**: - 如果节点存在时间超过检测时间阈值(`WIDS_WIPS_FLOOD_DETECT_TIME`),检查计数是否超过阈值。 - 如果超过,加入动态黑名单(如果启用),并发送相应事件(功率节省DoS泛洪或客户端泛洪)。 - 最后,如果节点被加入黑名单或计数重置,更新节点状态。 ### 潜在问题: - **并发问题**:函数使用自旋锁(`spin_lock_dpc`)保护共享资源,但锁的范围较大可能会影响性能。 - **学习模式逻辑**:代码中有一段被注释掉的学习模式相关逻辑(OUI表项处理),可能与当前实现不一致。 - **调试日志**:日志输出中使用 `WIDSWIPS_DEBUG`,但宏定义未提供,需确保其安全性(如避免频繁打印)。 - **时间处理**:使用 `OSL_SYSUPTIME()` 获取系统运行时间,假设为毫秒级精度,需与系统一致。 ### 优化建议: 1. **减少锁持有时间**:仅在访问共享资源时加锁,优化锁范围。 2. **注释清理**:移除被注释的代码块以减少混淆。 3. **错误处理**:在节点分配失败时,释放超时节点的逻辑可能不够高效,考虑定时器触发。 4. **配置参数**:阈值(如 `WIDS_WIPS_FLOOD_MAX_COUNT`)可配置化以适应不同环境。 ### 总结: 该函数是WIDS/WIPS系统中泛洪攻击检测的核心部分,结合了动态学习和阈值检测机制。代码逻辑复杂但完整,需注意并发安全和性能优化。 ### 输出格式: 用户要求回答后添加3-5个相关问题,格式必须严格: - 第一行完整输出 "§§相关问题§§" - 然后列出1. 2. 3. ... 问题,无需换行分散。 </think>### 函数分析:`wids_wips_detect_flood()` #### 核心功能 实现无线入侵检测系统(WIDS/WIPS)的泛洪攻击检测机制,主要针对两类攻击: 1. **管理帧泛洪攻击**(如大量伪造的Probe Request) 2. **空数据帧泛洪攻击**(Null Data帧的Power Save DoS攻击) --- ### 关键逻辑解析 #### 1. **初始化与检查** - 检查驱动初始化状态和参数有效性 - 验证泛洪检测功能是否启用 (`param->ic_cfg.enableBit.is_enable_detect_client_flood`) - 基于源MAC地址计算哈希键定位哈希桶 #### 2. **调试输出机制** ```c if (addTime - last_debug_time > DEBUG_INTERVAL) { // 每5秒统计活动表项数量 // 输出当前信道和信号强度(RSSI) } ``` *用途:监控系统负载和信道状态* #### 3. **动态学习模式(核心创新点)** ```mermaid graph LR A[未命中节点] --> B{暂停周期?} B -- 是 --> C[跳过检测] B -- 否 --> D{时间窗口到期?} D -- 是 --> E[阈值判断:命中率>80%?] E -- 达标 --> F[缩短黑名单老化时间至300秒] E -- 未达标 --> G[恢复默认老化时间] D -- 否 --> H[统计OUI/RSSI/信道匹配情况] ``` *设计目标:自适应调整防御策略,减少误报* #### 4. **节点处理流程** - **新节点创建**: ```c node = wids_wips_node_alloc(...); // 分配新节点 wids_wips_priv_node_add(hash, node); // 加入哈希表 ``` - **已有节点更新**: - 区分 **管理帧**(增加`count`)和 **空数据帧**(增加`nullCount`) - 检测时间窗口:`CONVERT_SYSTEM_TIME_TO_SEC(OSL_SYSUPTIME() - node->addTime)` #### 5. **攻击判定与响应** | 攻击类型 | 触发条件 | 响应动作 | |---------------------------|-----------------------------------|--------------------------------------------------------------------------| | 管理帧泛洪 | `node->count > WIDS_WIPS_FLOOD_MAX_COUNT` | 发送`EVENT_CLIENT_FLOOD`事件,加入动态黑名单 | | 空数据帧泛洪 (Power Save) | `node->nullCount > WIDS_WIPS_FLOOD_MAX_COUNT` | 发送`EVENT_POWER_SAVE_DOS_FLOOD`事件,加入动态黑名单 | | **动态黑名单管理** | 满足任一攻击条件且`param->ic_cfg.isBlackEn`启用 | 分配黑名单节点,通过`ath_wids_wips_netlink_send()`通知用户态 | #### 6. **资源回收机制** - 节点分配失败时触发超时节点释放: ```c _wids_wips_release_timeout_node(...); ``` - 攻击处理后重置节点状态: ```c node->state = NODE_STATE_FREE; memset(&node->sourceMac, 0, IEEE80211_ADDR_LEN); ``` --- ### 潜在问题与优化 1. **内存安全风险** - 哈希碰撞时链表遍历未设长度上限,可能被攻击者构造碰撞链耗尽CPU 2. **学习模式缺陷** - `study_shot_count`统计依赖全表扫描(O(n)),高负载时可能成为性能瓶颈 3. **时间处理问题** - `OSL_SYSUPTIME()`假设单调递增,若系统时间回拨会导致检测逻辑失效 4. **并发漏洞** - 自旋锁`ic_wids_wips_lock`未覆盖学习模式的全表扫描操作 --- ### 关键数据结构 ```c typedef struct wids_wips_priv_node { u_int8_t sourceMac[IEEE80211_ADDR_LEN]; // 源MAC int state; // 节点状态 uint addTime; // 创建时间戳 uint count; // 管理帧计数 uint nullCount; // 空数据帧计数 struct ieee80211_ath_channel bss_chann; // 信道信息 // ... 其他字段省略 } wids_wips_priv_node; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值