1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 /* ****************************************************************************
20 1 头文件包含
21 **************************************************************************** */
22 #include "hmac_encap_frame.h"
23
24 #ifdef __cplusplus
25 #if __cplusplus
26 extern "C" {
27 #endif
28 #endif
29
30 /* ****************************************************************************
31 3 函数实现
32 **************************************************************************** */
33 /* ****************************************************************************
34 功能描述 : 组sa query 请求帧
35 输入参数 : pst_mac_vap :mac vap结构体
36 puc_data :netbuf data指针
37 puc_da :目标用户的mac地址
38 trans_id :sa query ie,用于辨别response和request是否一致
39 返 回 值 : 帧头+帧体的长度
40 修改历史 :
41 1.日 期 : 2014年4月19日
42 作 者 : HiSilicon
43 修改内容 : 新生成函数
44 **************************************************************************** */
hmac_encap_sa_query_req(const mac_vap_stru * mac_vap,hi_u8 * puc_data,const hi_u8 * da_mac_addr,hi_u16 us_trans_id)45 hi_u16 hmac_encap_sa_query_req(const mac_vap_stru *mac_vap, hi_u8 *puc_data, const hi_u8 *da_mac_addr,
46 hi_u16 us_trans_id)
47 {
48 hi_u16 us_len;
49
50 if (mac_vap->mib_info == HI_NULL) {
51 return HI_ERR_CODE_PTR_NULL;
52 }
53
54 /* *********************************************************************** */
55 /* Management Frame Format */
56 /* -------------------------------------------------------------------- */
57 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
58 /* -------------------------------------------------------------------- */
59 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
60 /* -------------------------------------------------------------------- */
61 /* */
62 /* *********************************************************************** */
63 /* *********************************************************************** */
64 /* Set the fields in the frame header */
65 /* *********************************************************************** */
66 /* All the fields of the Frame Control Field are set to zero. Only the */
67 /* Type/Subtype field is set. */
68 mac_hdr_set_frame_control(puc_data, WLAN_FC0_SUBTYPE_ACTION);
69 /* Set DA */
70 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address1, WLAN_MAC_ADDR_LEN, da_mac_addr,
71 WLAN_MAC_ADDR_LEN) != EOK) {
72 return 0;
73 }
74 /* Set SA */
75 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address2, WLAN_MAC_ADDR_LEN,
76 mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) {
77 return 0;
78 }
79 /* Set SSID */
80 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address3, WLAN_MAC_ADDR_LEN, mac_vap->auc_bssid,
81 WLAN_MAC_ADDR_LEN) != EOK) {
82 return 0;
83 }
84 /* *********************************************************************** */
85 /* Set the contents of the frame body */
86 /* *********************************************************************** */
87 /* *********************************************************************** */
88 /* SA Query Frame - Frame Body */
89 /* --------------------------------------------------------------------- */
90 /* | Category |SA Query Action | Transaction Identifier | */
91 /* --------------------------------------------------------------------- */
92 /* |1 |1 |2 Byte | */
93 /* --------------------------------------------------------------------- */
94 /* */
95 /* *********************************************************************** */
96 puc_data[MAC_80211_FRAME_LEN] = MAC_ACTION_CATEGORY_SA_QUERY;
97 puc_data[MAC_80211_FRAME_LEN + 1] = MAC_SA_QUERY_ACTION_REQUEST; /* 1:偏移1 */
98 puc_data[MAC_80211_FRAME_LEN + 2] = (us_trans_id & 0x00FF); /* 2:偏移2 */
99 puc_data[MAC_80211_FRAME_LEN + 3] = (us_trans_id & 0xFF00) >> 8; /* 3:偏移1,8:向右移动8位 */
100
101 us_len = MAC_80211_FRAME_LEN + MAC_SA_QUERY_LEN;
102 return us_len;
103 }
104
105 /* ****************************************************************************
106 功能描述 : 组sa query 反馈帧
107 输入参数 : pst_hdr:sa query request frame
108 puc_data:sa query response frame
109 返 回 值 : 帧头+帧体的长度
110 修改历史 :
111 1.日 期 : 2014年4月19日
112 作 者 : HiSilicon
113 修改内容 : 新生成函数
114 **************************************************************************** */
hmac_encap_sa_query_rsp(const mac_vap_stru * mac_vap,const hi_u8 * hdr,hi_u8 * puc_data)115 hi_u16 hmac_encap_sa_query_rsp(const mac_vap_stru *mac_vap, const hi_u8 *hdr, hi_u8 *puc_data)
116 {
117 hi_u16 us_len;
118
119 if (mac_vap->mib_info == HI_NULL) {
120 return HI_ERR_CODE_PTR_NULL;
121 }
122
123 /* *********************************************************************** */
124 /* Management Frame Format */
125 /* -------------------------------------------------------------------- */
126 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
127 /* -------------------------------------------------------------------- */
128 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
129 /* -------------------------------------------------------------------- */
130 /* */
131 /* *********************************************************************** */
132 /* *********************************************************************** */
133 /* Set the fields in the frame header */
134 /* *********************************************************************** */
135 /* All the fields of the Frame Control Field are set to zero. Only the */
136 /* Type/Subtype field is set. */
137 mac_hdr_set_frame_control(puc_data, WLAN_FC0_SUBTYPE_ACTION);
138 /* Set DA */
139 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address1, WLAN_MAC_ADDR_LEN,
140 ((mac_ieee80211_frame_stru *)hdr)->auc_address2, WLAN_MAC_ADDR_LEN) != EOK) {
141 oam_error_log0(0, 0, "{hmac_encap_sa_query_rsp::mem safe function err!}");
142 return 0;
143 }
144 /* Set SA */
145 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address2, WLAN_MAC_ADDR_LEN,
146 mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) {
147 oam_error_log0(0, 0, "{hmac_encap_sa_query_rsp::mem safe function err!}");
148 return 0;
149 }
150 /* Set SSID */
151 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address3, WLAN_MAC_ADDR_LEN, mac_vap->auc_bssid,
152 WLAN_MAC_ADDR_LEN) != EOK) {
153 oam_error_log0(0, 0, "{hmac_encap_sa_query_rsp::mem safe function err!}");
154 return 0;
155 }
156 /* *********************************************************************** */
157 /* Set the contents of the frame body */
158 /* *********************************************************************** */
159 /* *********************************************************************** */
160 /* SA Query Frame - Frame Body */
161 /* --------------------------------------------------------------------- */
162 /* | Category |SA Query Action | Transaction Identifier | */
163 /* --------------------------------------------------------------------- */
164 /* |1 |1 |2 Byte | */
165 /* --------------------------------------------------------------------- */
166 /* */
167 /* *********************************************************************** */
168 puc_data[MAC_80211_FRAME_LEN] = hdr[MAC_80211_FRAME_LEN];
169 puc_data[MAC_80211_FRAME_LEN + 1] = MAC_SA_QUERY_ACTION_RESPONSE; /* 1:偏移1 */
170 puc_data[MAC_80211_FRAME_LEN + 2] = hdr[MAC_80211_FRAME_LEN + 2]; /* 2:偏移2 */
171 puc_data[MAC_80211_FRAME_LEN + 3] = hdr[MAC_80211_FRAME_LEN + 3]; /* 3:偏移3 */
172
173 us_len = MAC_80211_FRAME_LEN + MAC_SA_QUERY_LEN;
174 return us_len;
175 }
176
177 /* ****************************************************************************
178 功能描述 : 组去认证帧
179 **************************************************************************** */
hmac_mgmt_encap_deauth(const mac_vap_stru * mac_vap,hi_u8 * puc_data,const hi_u8 * da_mac_addr,hi_u16 err_code)180 hi_u16 hmac_mgmt_encap_deauth(const mac_vap_stru *mac_vap, hi_u8 *puc_data, const hi_u8 *da_mac_addr, hi_u16 err_code)
181 {
182 hi_u8 auc_bssid[WLAN_MAC_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
183 mac_ieee80211_frame_stru *mac_hdr = (mac_ieee80211_frame_stru *)puc_data;
184
185 /* *********************************************************************** */
186 /* Management Frame Format */
187 /* -------------------------------------------------------------------- */
188 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
189 /* -------------------------------------------------------------------- */
190 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
191 /* -------------------------------------------------------------------- */
192 /* */
193 /* *********************************************************************** */
194 /* *********************************************************************** */
195 /* Set the fields in the frame header */
196 /* *********************************************************************** */
197 /* All the fields of the Frame Control Field are set to zero. Only the */
198 /* Type/Subtype field is set. */
199 mac_hdr_set_frame_control(puc_data, WLAN_FC0_SUBTYPE_DEAUTH);
200 /* Set DA to address of unauthenticated STA */
201 if (memcpy_s(mac_hdr->auc_address1, WLAN_MAC_ADDR_LEN, da_mac_addr, WLAN_MAC_ADDR_LEN) != EOK) {
202 return 0;
203 }
204 #ifdef _PRE_WLAN_FEATURE_P2P
205 if (err_code & MAC_SEND_TWO_DEAUTH_FLAG) {
206 mac_vap_stru *up_vap1 = HI_NULL;
207 mac_vap_stru *up_vap2 = HI_NULL;
208 err_code = err_code & ~MAC_SEND_TWO_DEAUTH_FLAG;
209
210 mac_device_stru *mac_dev = mac_res_get_dev();
211 if (mac_device_find_2up_vap(mac_dev, &up_vap1, &up_vap2) == HI_SUCCESS) {
212 /* 获取另外一个VAP,组帧时修改地址2为另外1个VAP的MAC地址 */
213 up_vap2 = (mac_vap->vap_id != up_vap1->vap_id) ? up_vap1 : up_vap2;
214 if (up_vap2->mib_info == HI_NULL) {
215 return 0;
216 }
217 if ((memcpy_s(mac_hdr->auc_address2, WLAN_MAC_ADDR_LEN,
218 up_vap2->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) ||
219 (memcpy_s(mac_hdr->auc_address3, WLAN_MAC_ADDR_LEN, up_vap2->auc_bssid, WLAN_MAC_ADDR_LEN) != EOK)) {
220 return 0;
221 }
222 }
223 } else {
224 #endif
225 if (mac_vap->mib_info == HI_NULL) {
226 return 0;
227 }
228 /* SA is the dot11MACAddress */
229 if (memcpy_s(mac_hdr->auc_address2, WLAN_MAC_ADDR_LEN,
230 mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) {
231 return 0;
232 }
233 /*
234 * 针对50行整改,先填写BSSID后对BSSID进行全0比较
235 * STA处于FAKE_UP状态,mac vap中bssid为全0,deauth帧对端不处理,改为填写da。
236 */
237 if (memcpy_s(mac_hdr->auc_address3, WLAN_MAC_ADDR_LEN, mac_vap->auc_bssid, WLAN_MAC_ADDR_LEN) != EOK) {
238 return 0;
239 }
240 if ((mac_vap->vap_mode == WLAN_VAP_MODE_BSS_STA) &&
241 (memcmp(mac_vap->auc_bssid, auc_bssid, WLAN_MAC_ADDR_LEN) == 0)) {
242 if (memcpy_s(mac_hdr->auc_address3, WLAN_MAC_ADDR_LEN, da_mac_addr, WLAN_MAC_ADDR_LEN) != EOK) {
243 return 0;
244 }
245 }
246 #ifdef _PRE_WLAN_FEATURE_P2P
247 }
248 #endif
249 /* *********************************************************************** */
250 /* Set the contents of the frame body */
251 /* *********************************************************************** */
252 /* *********************************************************************** */
253 /* Deauthentication Frame - Frame Body */
254 /* --------------------------------------------------------------------- */
255 /* | Reason Code | */
256 /* --------------------------------------------------------------------- */
257 /* |2 Byte | */
258 /* --------------------------------------------------------------------- */
259 /* */
260 /* *********************************************************************** */
261 /* Set Reason Code to 'Class2 error' */
262 puc_data[MAC_80211_FRAME_LEN] = (err_code & 0x00FF);
263 puc_data[MAC_80211_FRAME_LEN + 1] = (err_code & 0xFF00) >> 8; /* 1:偏移1,8:向右位移8 */
264
265 return (MAC_80211_FRAME_LEN + WLAN_REASON_CODE_LEN);
266 }
267
268 /* ****************************************************************************
269 功能描述 : 组去关联帧
270 输入参数 : vap指针,DA,ErrCode
271 输出参数 : 帧缓冲区
272 返 回 值 : 帧长度
273 修改历史 :
274 1.日 期 : 2013年12月28日
275 作 者 : HiSilicon
276 修改内容 : 新生成函数
277 **************************************************************************** */
hmac_mgmt_encap_disassoc(const mac_vap_stru * mac_vap,hi_u8 * puc_data,const hi_u8 * da_mac_addr,hi_u16 us_err_code)278 hi_u16 hmac_mgmt_encap_disassoc(const mac_vap_stru *mac_vap, hi_u8 *puc_data, const hi_u8 *da_mac_addr,
279 hi_u16 us_err_code)
280 {
281 hi_u16 us_disassoc_len = 0;
282
283 /* *********************************************************************** */
284 /* Management Frame Format */
285 /* -------------------------------------------------------------------- */
286 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
287 /* -------------------------------------------------------------------- */
288 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
289 /* -------------------------------------------------------------------- */
290 /* */
291 /* *********************************************************************** */
292 /* *********************************************************************** */
293 /* 设置帧头 */
294 /* *********************************************************************** */
295 /* 设置subtype */
296 mac_hdr_set_frame_control(puc_data, WLAN_FC0_SUBTYPE_DISASSOC);
297
298 if (mac_vap->mib_info == HI_NULL) {
299 us_disassoc_len = 0;
300 oam_error_log0(mac_vap->vap_id, OAM_SF_AUTH, "hmac_mgmt_encap_disassoc: pst_mac_vap mib ptr null.");
301 return us_disassoc_len;
302 }
303 /* 设置DA */
304 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address1, WLAN_MAC_ADDR_LEN, da_mac_addr,
305 WLAN_MAC_ADDR_LEN) != EOK) {
306 return 0;
307 }
308 /* 设置SA */
309 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address2, WLAN_MAC_ADDR_LEN,
310 mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) {
311 return 0;
312 }
313
314 #ifdef _PRE_WLAN_FEATURE_MESH
315 /* Mesh 下直接填充本设备mac 地址,不判断 */
316 if (mac_vap->vap_mode == WLAN_VAP_MODE_MESH) {
317 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address3, WLAN_MAC_ADDR_LEN,
318 mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id, WLAN_MAC_ADDR_LEN) != EOK) {
319 return 0;
320 }
321 } else {
322 /* 设置bssid */
323 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address3, WLAN_MAC_ADDR_LEN,
324 mac_vap->vap_mode == WLAN_VAP_MODE_BSS_AP ? mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id :
325 mac_vap->auc_bssid, WLAN_MAC_ADDR_LEN) != EOK) {
326 return 0;
327 }
328 }
329 #else
330 /* 设置bssid */
331 if (memcpy_s(((mac_ieee80211_frame_stru *)puc_data)->auc_address3, WLAN_MAC_ADDR_LEN,
332 mac_vap->vap_mode == WLAN_VAP_MODE_BSS_AP ?
333 mac_vap->mib_info->wlan_mib_sta_config.auc_dot11_station_id : mac_vap->auc_bssid,
334 WLAN_MAC_ADDR_LEN) != EOK) {
335 return 0;
336 }
337 #endif
338
339 /* *********************************************************************** */
340 /* Disassociation 帧 - 帧体 */
341 /* --------------------------------------------------------------------- */
342 /* | Reason Code | */
343 /* --------------------------------------------------------------------- */
344 /* |2 Byte | */
345 /* --------------------------------------------------------------------- */
346 /* */
347 /* *********************************************************************** */
348 /* 设置reason code */
349 puc_data[MAC_80211_FRAME_LEN] = (us_err_code & 0x00FF);
350 puc_data[MAC_80211_FRAME_LEN + 1] = (us_err_code & 0xFF00) >> 8; /* 1:偏移1,8:向右位移8 */
351
352 us_disassoc_len = MAC_80211_FRAME_LEN + WLAN_REASON_CODE_LEN;
353
354 return us_disassoc_len;
355 }
356
357 /* ****************************************************************************
358 功能描述 : 检查当前STA是否支持AP的基本速率
359 修改历史 :
360 1.日 期 : 2013年7月9日
361 作 者 : HiSilicon
362 修改内容 : 新生成函数
363 **************************************************************************** */
hmac_check_sta_base_rate(hi_u8 * user,mac_status_code_enum_uint16 * pen_status_code)364 hi_void hmac_check_sta_base_rate(hi_u8 *user, mac_status_code_enum_uint16 *pen_status_code)
365 {
366 hi_u8 num_basic_rates;
367 hi_u8 loop;
368 hi_u8 index;
369 hi_u8 found;
370 hi_u8 num_rates;
371 hi_u8 ap_base_rate;
372 mac_vap_stru *mac_vap = HI_NULL;
373 hmac_user_stru *hmac_user = HI_NULL;
374
375 hmac_user = (hmac_user_stru *)user;
376
377 /* 获取VAP */
378 mac_vap = mac_vap_get_vap_stru(hmac_user->base_user->vap_id);
379 if (mac_vap == HI_NULL) {
380 return;
381 }
382
383 num_basic_rates = mac_vap->curr_sup_rates.br_rate_num;
384 num_rates = hmac_user->op_rates.rs_nrates;
385
386 for (loop = 0; loop < num_basic_rates; loop++) {
387 found = HI_FALSE;
388 ap_base_rate = mac_vap_get_curr_baserate(mac_vap, loop);
389
390 for (index = 0; index < num_rates; index++) {
391 if ((hmac_user->op_rates.auc_rs_rates[index] & 0x7F) == (ap_base_rate & 0x7F)) {
392 found = HI_TRUE;
393 break;
394 }
395 }
396
397 /* 不支持某基本速率,返回false */
398 if (found == HI_FALSE) {
399 *pen_status_code = MAC_UNSUP_RATE;
400 return;
401 }
402 }
403 }
404
405 #ifdef __cplusplus
406 #if __cplusplus
407 }
408 #endif
409 #endif
410