• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description: hook function for wifi promiscuous.
15  */
16 
17 /* 混杂模式在linux上编译不过,先屏蔽,后续特性责任人做适配 */
18 #include "hmac_promisc.h"
19 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
20 #include "soc_zdiag.h"
21 #include "hal_mac_reg.h"
22 #else
23 #include "mac_resource_ext.h"
24 #endif
25 #include "hmac_sta_pm.h"
26 #include "oam_ext_if.h"
27 #include "oal_net.h"
28 #include "mac_frame.h"
29 #include "mac_device_ext.h"
30 #include "dmac_ext_if_device.h"
31 #include "hmac_config.h"
32 #include "msg_psm_rom.h"
33 #include "hmac_mgmt_classifier.h"
34 #include "hmac_feature_interface.h"
35 #include "hmac_hook.h"
36 
37 #ifdef __cplusplus
38 #if __cplusplus
39 extern "C" {
40 #endif
41 #endif
42 
43 #undef  THIS_FILE_ID
44 #define THIS_FILE_ID OAM_FILE_ID_OAM_PROMISC_C
45 
46 #define WLAN_PROCMIS_ZDIAG_ID       0x7580
47 #define WLAN_PROMISC_MODE_NUM       4
48 
49 static wlan_promisc_mode_stru g_promisc_st = {
50     .promis_count = {{{0}}}
51 };
52 
53 static osal_u8 g_custom_en = 0;
54 static osal_u8 g_promisc_switch = 0;
55 static osal_u8 g_promisc_mode = 0;
56 
57 /* 函数功能: 清零混杂模式帧计数 */
hmac_promisc_clear_counts(void)58 OAL_STATIC osal_void hmac_promisc_clear_counts(void)
59 {
60     memset_s(g_promisc_st.promis_count, sizeof(g_promisc_st.promis_count), 0, sizeof(g_promisc_st.promis_count));
61 }
62 
63 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
hmac_promis_send_custom_frame(hmac_vap_stru * hmac_vap,const oal_netbuf_stru * netbuf)64 OAL_STATIC osal_void hmac_promis_send_custom_frame(hmac_vap_stru *hmac_vap, const oal_netbuf_stru *netbuf)
65 {
66     const dmac_rx_ctl_stru *rx_ctl = OSAL_NULL;
67     const mac_rx_ctl_stru *rx_info = OSAL_NULL;
68 
69     if (netbuf == OSAL_NULL) {
70         return;
71     }
72 
73     if (g_custom_en == 0) {
74         return;
75     }
76 
77     rx_ctl = (dmac_rx_ctl_stru *)oal_netbuf_cb_const(netbuf); /* 获取帧头信息 */
78     rx_info = (const mac_rx_ctl_stru *)(&(rx_ctl->rx_info));
79     hmac_rx_send_report_frame_msg(hmac_vap, rx_info, rx_ctl->rx_statistic.rssi_dbm, WLAN_MSG_H2W_UPLOAD_PROMIS);
80     return;
81 }
82 #endif
83 
hmac_show_promisc_res_by_mode(osal_u8 bit_num,osal_u8 frame_type,osal_u8 subtype_num,osal_u8 frame_mode)84 OAL_STATIC osal_void hmac_show_promisc_res_by_mode(osal_u8 bit_num, osal_u8 frame_type,
85     osal_u8 subtype_num, osal_u8 frame_mode)
86 {
87     osal_u8 i;
88     osal_u8 promisc_mode = g_promisc_mode;
89     osal_u8 type = (frame_type == WLAN_MANAGEMENT) ? WLAN_FC0_TYPE_MGT : WLAN_FC0_TYPE_DATA;
90 
91     if (((promisc_mode >> bit_num) & 0x1) != OSAL_FALSE) {
92         for (i = 0; i < subtype_num; i++) {
93             if (g_promisc_st.promis_count[frame_type][i][frame_mode] != 0) {
94                 oam_warning_log3(0, 0, "type[%d], sub_type[%d], count[%d]\r\n",
95                     type, i, g_promisc_st.promis_count[frame_type][i][frame_mode]);
96             }
97         }
98     }
99 }
100 
hmac_show_80211_frame_promisc_statistic(osal_void)101 OAL_STATIC osal_void hmac_show_80211_frame_promisc_statistic(osal_void)
102 {
103     osal_u8 i;
104     wlan_promisc_query_stru promisc_query_module[WLAN_PROMISC_MODE_NUM] = {
105         {0, WLAN_DATA_BASICTYPE, WLAN_DATA_SUBTYPE_MGMT, 1}, /* bit0 多播、广播数据帧打开 */
106         {1, WLAN_DATA_BASICTYPE, WLAN_MGMT_SUBTYPE_BUTT, 0}, /* bit1 单播数据帧打开 */
107         {2, WLAN_MANAGEMENT, WLAN_MGMT_SUBTYPE_BUTT, 1}, /* bit2 多播、广播管理帧打开 */
108         {3, WLAN_MANAGEMENT, WLAN_MGMT_SUBTYPE_BUTT, 0}, /* bit3 单播管理帧打开 */
109     };
110 
111     for (i = 0; i < osal_array_size(promisc_query_module); i++) {
112         hmac_show_promisc_res_by_mode(promisc_query_module[i].bit_num, promisc_query_module[i].frame_type,
113             promisc_query_module[i].subtype_num, promisc_query_module[i].frame_mode);
114     }
115 }
116 
117 /* 函数功能: 混杂模式帧类型统计信息串口打印 */
hmac_80211_frame_promis_proc(hmac_vap_stru * hmac_vap,const mac_ieee80211_frame_stru * frame_hdr,const mac_rx_ctl_stru * rx_info,osal_s8 rssi)118 OAL_STATIC osal_void hmac_80211_frame_promis_proc(hmac_vap_stru *hmac_vap,
119     const mac_ieee80211_frame_stru *frame_hdr, const mac_rx_ctl_stru *rx_info, osal_s8 rssi)
120 {
121     osal_u8 is_multicast, type, sub_type, filter, frame_mode;
122 
123     /* 混杂模式只处理RX方向的 802.11报文(包含beacon) */
124     is_multicast = (frame_hdr->frame_control.to_ds == 0) ?
125         ether_is_multicast(frame_hdr->address1) : ether_is_multicast(frame_hdr->address3);
126     frame_mode = (is_multicast == 0) ? 0 : 1; /* 0:表示单播,1:表示广播 */
127     type = frame_hdr->frame_control.type;
128     sub_type = frame_hdr->frame_control.sub_type;
129     filter = (osal_u8)g_promisc_mode;
130 
131     if (type == WLAN_CONTROL) { /* 控制帧处理 */
132         return;
133     } else if (type == WLAN_MANAGEMENT) { /* 管理帧处理 */
134         g_promisc_st.promis_count[type][sub_type][frame_mode]++;
135     } else { /* 数据帧处理 */
136         g_promisc_st.promis_count[type][sub_type][frame_mode]++;
137     }
138 
139     /* bit0 多播、广播数据帧没有打开 */
140     if (((filter & 0x1) == OSAL_FALSE) && ((type == WLAN_DATA_BASICTYPE) && (is_multicast != 0))) {
141         return;
142     }
143     /* bit1 单播数据帧没有打开 */
144     if ((((filter >> 1) & 0x1) == OSAL_FALSE) && ((type == WLAN_DATA_BASICTYPE) && (is_multicast == 0))) {
145         return;
146     }
147     /* bit2 多播、广播管理帧没有打开 */
148     if ((((filter >> 2) & 0x1) == OSAL_FALSE) && ((type == WLAN_MANAGEMENT) && (is_multicast != 0))) {
149         return;
150     }
151     /* bit3 单播管理帧没有打开 */
152     if ((((filter >> 3) & 0x1) == OSAL_FALSE) && ((type == WLAN_MANAGEMENT) && (is_multicast == 0))) {
153         return;
154     }
155 
156 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
157     hmac_rx_send_report_frame_msg(hmac_vap, rx_info, rssi, WLAN_MSG_H2W_UPLOAD_PROMIS);
158 #endif
159 }
160 
hmac_80211_frame_promis_data2diag(const mac_ieee80211_frame_stru * wlan_frame,osal_u16 frame_len)161 OAL_STATIC osal_void hmac_80211_frame_promis_data2diag(const mac_ieee80211_frame_stru *wlan_frame, osal_u16 frame_len)
162 {
163 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
164 #ifdef _PRE_WLAN_FEATURE_WS73
165     diag_option option = DIAG_OPTION_INIT_VAL;
166 #else
167     diag_option_t option = DIAG_OPTION_INIT_VAL;
168 #endif
169 
170     oam_warning_log1(0, 0, "{dmac_80211_frame_promis_data2diag::frame_len[%d].}", frame_len);
171 #ifndef _PRE_LITEOS_SDK_
172     uapi_zdiag_report_packet(WLAN_PROCMIS_ZDIAG_ID, &option, (td_u8 *)wlan_frame, (td_u16)frame_len, TD_FALSE);
173 #endif
174 #endif
175 }
176 
177 /*****************************************************************************
178  功能描述  : 混杂模式的处理
179 *****************************************************************************/
hmac_rx_frame_promis_proc(oal_netbuf_stru ** netbuf,hmac_vap_stru * hmac_vap)180 OAL_STATIC osal_u32 hmac_rx_frame_promis_proc(oal_netbuf_stru **netbuf, hmac_vap_stru *hmac_vap)
181 {
182     dmac_rx_ctl_stru *rx_ctl;
183     const mac_rx_ctl_stru *rx_info = OSAL_NULL;
184     const mac_ieee80211_frame_stru *frame_hdr;
185 
186     if (g_promisc_switch == 0) {
187         return OAL_CONTINUE;
188     }
189 
190     rx_ctl = (dmac_rx_ctl_stru *)oal_netbuf_cb_const(*netbuf); /* 获取帧头信息 */
191     rx_info = (const mac_rx_ctl_stru *)(&(rx_ctl->rx_info));
192     frame_hdr = (mac_ieee80211_frame_stru *)oal_netbuf_header(*netbuf);
193     hmac_80211_frame_promis_proc(hmac_vap, frame_hdr, rx_info, rx_ctl->rx_statistic.rssi_dbm);
194     hmac_80211_frame_promis_data2diag(frame_hdr, rx_ctl->rx_info.frame_len);
195 
196     return OAL_CONTINUE;
197 }
198 
199 /*****************************************************************************
200  功能描述  : 混杂模式的处理
201 *****************************************************************************/
hmac_promisc_set_monitor_hal_reg(osal_u8 promis_switch)202 OAL_STATIC osal_void hmac_promisc_set_monitor_hal_reg(osal_u8 promis_switch)
203 {
204     hal_rx_filter_set_rx_flt_en(promis_switch);
205 }
206 
hmac_sta_rx_deauth_req_proc_for_promisc(hmac_vap_stru * hmac_vap,const osal_u8 * mac_hdr)207 OAL_STATIC osal_u32 hmac_sta_rx_deauth_req_proc_for_promisc(hmac_vap_stru *hmac_vap, const osal_u8 *mac_hdr)
208 {
209     osal_u8 *da = OSAL_NULL;
210     hmac_device_stru *hmac_device = OSAL_NULL;
211 
212     mac_rx_get_da((mac_ieee80211_frame_stru *)mac_hdr, &da);
213 
214     hmac_device = (hmac_device_stru *)hmac_res_get_mac_dev_etc(hmac_vap->device_id);
215     if (osal_unlikely(hmac_device == OSAL_NULL)) {
216         oam_warning_log1(0, OAM_SF_AUTH,
217             "vap_id[%d] {hmac_sta_rx_deauth_req_proc_for_promisc::hmac_device is null}", hmac_vap->vap_id);
218         return OAL_ERR_CODE_MAC_DEVICE_NULL;
219     }
220 
221     /* 混杂模式下,判断关联之后如果收到了AP发给其他STA的去关联帧,丢弃 */
222     if ((g_promisc_switch != 0) &&
223         (memcmp(da, hmac_vap->mib_info->wlan_mib_sta_config.dot11_station_id, WLAN_MAC_ADDR_LEN) != 0)) {
224         oam_warning_log1(0, OAM_SF_AUTH,
225             "vap_id[%d] {hmac_sta_rx_deauth_req_proc_for_promisc::rx deauth for other STA}", hmac_vap->vap_id);
226         return OAL_FAIL;
227     }
228 
229     return OAL_SUCC;
230 }
231 
232 hmac_netbuf_hook_stru g_promisc_data_netbuf_hook = {
233     .hooknum = HMAC_FRAME_DATA_RX_EVENT_D2H,
234     .priority = HMAC_HOOK_PRI_MIDDLE,
235     .hook_func = hmac_rx_frame_promis_proc,
236 };
237 
238 hmac_netbuf_hook_stru g_promisc_mgmt_netbuf_hook = {
239     .hooknum = HMAC_FRAME_MGMT_RX_EVENT_D2H,
240     .priority = HMAC_HOOK_PRI_MIDDLE,
241     .hook_func = hmac_rx_frame_promis_proc,
242 };
243 
hmac_promis_feature_hook_register(osal_void)244 OAL_STATIC osal_void hmac_promis_feature_hook_register(osal_void)
245 {
246     /* 注册对外接口 */
247     (osal_void)hmac_register_netbuf_hook(&g_promisc_data_netbuf_hook);
248     (osal_void)hmac_register_netbuf_hook(&g_promisc_mgmt_netbuf_hook);
249     hmac_feature_hook_register(HMAC_FHOOK_PROMIS_RX_DEAUTH_REQ_PROC, hmac_sta_rx_deauth_req_proc_for_promisc);
250 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
251     hmac_feature_hook_register(HMAC_FHOOK_PROMIS_SEND_CUSTOM_FRAME, hmac_promis_send_custom_frame);
252 #endif
253     return;
254 }
255 
hmac_promis_feature_hook_unregister(osal_void)256 OAL_STATIC osal_void hmac_promis_feature_hook_unregister(osal_void)
257 {
258     /* 去注册对外接口 */
259     (osal_void)hmac_unregister_netbuf_hook(&g_promisc_data_netbuf_hook);
260     (osal_void)hmac_unregister_netbuf_hook(&g_promisc_mgmt_netbuf_hook);
261     hmac_feature_hook_unregister(HMAC_FHOOK_PROMIS_RX_DEAUTH_REQ_PROC);
262 #if defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
263     hmac_feature_hook_unregister(HMAC_FHOOK_PROMIS_SEND_CUSTOM_FRAME);
264 #endif
265     return;
266 }
267 
268 /*****************************************************************************
269  功能描述  : 配置芯片是否接收其他BSS网络内发的包
270  修改历史      :
271   1.日    期   : 2016年3月14日
272     修改内容   : 新生成函数
273 *****************************************************************************/
hmac_config_set_monitor_switch(hmac_vap_stru * hmac_vap,frw_msg * msg)274 OAL_STATIC osal_s32 hmac_config_set_monitor_switch(hmac_vap_stru *hmac_vap, frw_msg *msg)
275 {
276     mac_cfg_ps_open_stru ps_open;
277     hal_to_dmac_device_stru *hal_device = hmac_vap->hal_device;
278     osal_u8 value = msg->data[0];
279     osal_u8 promisc_switch = msg->data[1];
280 
281     if (osal_unlikely(hal_device == OSAL_NULL)) {
282         oam_error_log1(0, OAM_SF_CFG, "vap_id[%d] {hmac_config_set_monitor_switch::hal_dev null}", hmac_vap->vap_id);
283         return OAL_ERR_CODE_PTR_NULL;
284     }
285     if (promisc_switch == 2) { /* 2:混杂统计打印 */
286         hmac_show_80211_frame_promisc_statistic();
287         return OAL_SUCC;
288     }
289 
290     g_custom_en = 0;
291     /* 有其他过滤方式时,custom_en:4 不生效 */
292     if ((((value >> 4) & 0x1) == OSAL_TRUE) && (promisc_switch == 0)) {
293         g_custom_en = 1;
294     }
295     g_promisc_switch = promisc_switch;
296     g_promisc_mode = value & 0xF;
297     oam_warning_log2(0, OAM_SF_CFG, "{hmac_config_set_monitor_switch::promisc_switch[%d], promisc_cfg[%d]",
298         g_promisc_switch, g_promisc_mode);
299 
300     hal_device->promis_switch = promisc_switch;
301     if (promisc_switch == 1) {
302         /* 混杂开启时注册 */
303         wifi_printf("hmac_config_set_monitor_switch:: switch[%d] mode[%d]\r\n", promisc_switch, value);
304         hmac_promis_feature_hook_register();
305     } else {
306         /* 混杂关闭时注册 */
307         hmac_promis_feature_hook_unregister();
308     }
309     hmac_hal_device_sync(hal_device);
310     hmac_promisc_clear_counts(); /* 混杂模式统计数组清零 */
311     ps_open.pm_ctrl_type = MAC_STA_PM_CTRL_TYPE_MONITOR; /* monitor模式低功耗控制位 */
312 
313     if (hal_device->promis_switch == 0) { /* 关闭报文上报 */
314         ps_open.pm_enable = MAC_STA_PM_SWITCH_ON; /* 开启低功耗 */
315     } else {
316         ps_open.pm_enable = MAC_STA_PM_SWITCH_OFF; /* 关闭低功耗 */
317     }
318     oam_warning_log2(0, OAM_SF_CFG, "Setting Promisc mode%d! Power Manager mode%d\r\n", g_promisc_mode,
319         ps_open.pm_enable);
320     if (hmac_vap->vap_mode == WLAN_VAP_MODE_BSS_STA) { /* 须先配置低功耗模式,再配置寄存器 */
321         hmac_set_sta_pm_on_cb(hmac_vap, &ps_open);
322     }
323 
324     hmac_promisc_set_monitor_hal_reg(g_promisc_mode);
325 
326     return OAL_SUCC;
327 }
328 
hmac_promis_init(osal_void)329 osal_u32 hmac_promis_init(osal_void)
330 {
331     /* 消息注册 */
332     /* W2H */
333     frw_msg_hook_register(WLAN_MSG_W2H_CFG_MONITOR_EN, hmac_config_set_monitor_switch);
334     return OAL_SUCC;
335 }
336 
hmac_promis_deinit(osal_void)337 osal_void hmac_promis_deinit(osal_void)
338 {
339     /* 消息去注册 */
340     frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_MONITOR_EN);
341     return;
342 }
343 
344 #ifdef __cplusplus
345 #if __cplusplus
346 }
347 #endif
348 #endif
349