• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   头文件包含
21 **************************************************************************** */
22 #include "oal_ext_if.h"
23 #include "wlan_types.h"
24 #include "mac_vap.h"
25 #include "mac_device.h"
26 #include "mac_data.h"
27 
28 #ifdef __cplusplus
29 #if __cplusplus
30 extern "C" {
31 #endif
32 #endif
33 
34 /* ****************************************************************************
35   函数实现
36 **************************************************************************** */
37 /* ****************************************************************************
38  功能描述  : 从带mac头的80211帧中获取以太类型
39  修改历史      :
40   1.日    期   : 2015年7月6日
41     作    者   : HiSilicon
42     修改内容   : 新生成函数
43 **************************************************************************** */
mac_get_data_type_from_80211(const oal_netbuf_stru * netbuf,hi_u16 us_mac_hdr_len)44 hi_u8 mac_get_data_type_from_80211(const oal_netbuf_stru *netbuf, hi_u16 us_mac_hdr_len)
45 {
46     mac_llc_snap_stru *snap = HI_NULL;
47 
48     if (netbuf == HI_NULL) {
49         return MAC_DATA_BUTT;
50     }
51     snap = (mac_llc_snap_stru *)(oal_netbuf_data(netbuf) + us_mac_hdr_len);
52     return mac_get_data_type_from_8023((hi_u8 *)snap, MAC_NETBUFF_PAYLOAD_SNAP);
53 }
54 
55 /* ****************************************************************************
56  功能描述  : 判断该帧是否为4 次握手的EAPOL KEY 单播密钥协商帧
57  输入参数  : mac_eapol_header_stru  *pst_eapol_header
58  返 回 值  : hi_u8
59  修改历史      :
60   1.日    期   : 2015年8月13日
61     作    者   : HiSilicon
62     修改内容   : 新生成函数
63 **************************************************************************** */
mac_is_eapol_key_ptk(mac_eapol_header_stru * eapol_header)64 hi_u8 mac_is_eapol_key_ptk(mac_eapol_header_stru *eapol_header)
65 {
66     mac_eapol_key_stru *key = HI_NULL;
67 
68     if (IEEE802_1X_TYPE_EAPOL_KEY == eapol_header->type) {
69         if ((hi_u16)(oal_net2host_short(eapol_header->us_length)) >= (hi_u16)sizeof(mac_eapol_key_stru)) {
70             key = (mac_eapol_key_stru *)(eapol_header + 1);
71             if (key->auc_key_info[1] & WPA_KEY_INFO_KEY_TYPE) {
72                 return HI_TRUE;
73             }
74         }
75     }
76     return HI_FALSE;
77 }
78 
79 /* ****************************************************************************
80  功能描述  : 判断是否是dhcp帧 port
81  修改历史      :
82   1.日    期   : 2014年6月27日
83     作    者   : HiSilicon
84 **************************************************************************** */
mac_is_dhcp_port(mac_ip_header_stru * ip_hdr)85 WIFI_ROM_TEXT hi_u8 mac_is_dhcp_port(mac_ip_header_stru *ip_hdr)
86 {
87     udp_hdr_stru *udp_hdr = HI_NULL;
88     if ((ip_hdr->protocol == MAC_UDP_PROTOCAL) && ((oal_net2host_short(ip_hdr->us_frag_off) & 0x1FFF) == 0)) {
89         udp_hdr = (udp_hdr_stru *)(ip_hdr + 1);
90 
91         if (oal_net2host_short(udp_hdr->us_des_port) == 67 || /* 67 端口为dhcp端口 */
92             oal_net2host_short(udp_hdr->us_des_port) == 68) { /* 68 端口也为dhcp端口 */
93             return HI_TRUE;
94         }
95     }
96     return HI_FALSE;
97 }
98 
mac_dhcp_get_type(hi_u8 * pos,const hi_u8 * packet_end,hi_u8 type)99 WIFI_ROM_TEXT hi_u8 *mac_dhcp_get_type(hi_u8 *pos, const hi_u8 *packet_end, hi_u8 type)
100 {
101     hi_u8 *opt = HI_NULL;
102     if (pos == HI_NULL) {
103         oam_warning_log0(0, OAM_SF_PWR, "{mac_dhcp_get_type::pos is null.}");
104         return HI_NULL;
105     }
106 
107     if (packet_end == HI_NULL) {
108         oam_warning_log0(0, OAM_SF_PWR, "{mac_dhcp_get_type::packet_end is null.}");
109         return HI_NULL;
110     }
111 
112     /* 获取 DHCP 类型 */
113     while ((pos < packet_end) && (*pos != 0xFF)) {
114         opt = pos++;
115 
116         /* Padding */
117         if (*opt == 0) {
118             continue;
119         }
120         pos += *pos + 1;
121         if (pos >= packet_end) {
122             break;
123         }
124         /* Message Type */
125         if ((type == *opt) && (opt[1] != 0)) {
126             return opt;
127         }
128     }
129 
130     return HI_NULL;
131 }
132 
133 /* ****************************************************************************
134  功能描述  : 判断是否是nd帧
135  修改历史      :
136   1.日    期   : 2014年8月7日
137     作    者   : HiSilicon
138     修改内容   : 新生成函数
139 **************************************************************************** */
mac_is_nd(oal_ipv6hdr_stru * ipv6hdr)140 WIFI_ROM_TEXT hi_u8 mac_is_nd(oal_ipv6hdr_stru *ipv6hdr)
141 {
142     oal_icmp6hdr_stru *icmp6hdr = HI_NULL;
143 
144     if (ipv6hdr->nexthdr == OAL_IPPROTO_ICMPV6) {
145         icmp6hdr = (oal_icmp6hdr_stru *)(ipv6hdr + 1);
146         if ((icmp6hdr->icmp6_type == MAC_ND_RSOL) || (icmp6hdr->icmp6_type == MAC_ND_RADVT) ||
147             (icmp6hdr->icmp6_type == MAC_ND_NSOL) || (icmp6hdr->icmp6_type == MAC_ND_NADVT) ||
148             (icmp6hdr->icmp6_type == MAC_ND_RMES)) {
149             return HI_TRUE;
150         }
151     }
152     return HI_FALSE;
153 }
154 
mac_get_ipv4_data_type(mac_ip_header_stru * ip)155 WIFI_ROM_TEXT static hi_u8 mac_get_ipv4_data_type(mac_ip_header_stru *ip)
156 {
157     udp_hdr_stru *udp_hdr = HI_NULL;
158     dhcp_message_stru *dhcp_message = HI_NULL;
159     hi_u8 *tmp = HI_NULL;
160     hi_u8 datatype = MAC_DATA_BUTT;
161 
162     if (mac_is_dhcp_port(ip)) {
163         udp_hdr = (udp_hdr_stru *)(ip + 1);
164         dhcp_message = (dhcp_message_stru *)(udp_hdr + 1);
165         tmp = mac_dhcp_get_type(dhcp_message->options, dhcp_message->options + sizeof(dhcp_message->options),
166             DHCP_OPT_MESSAGETYPE);
167         if (tmp == HI_NULL) {
168             datatype = MAC_DATA_BUTT;
169         } else {
170             if (*(tmp + 2) == DHCP_DISCOVER) { /* 偏移2 byte,获取DHCP type */
171                 datatype = MAC_DATA_DHCP_DISCOVER;
172             } else if (*(tmp + 2) == DHCP_OFFER) { /* 偏移2 byte,获取DHCP type */
173                 datatype = MAC_DATA_DHCP_OFFER;
174             } else if (*(tmp + 2) == DHCP_REQUEST) { /* 偏移2 byte,获取DHCP type */
175                 datatype = MAC_DATA_DHCP_REQ;
176             } else if (*(tmp + 2) == DHCP_ACK) { /* 偏移2 byte,获取DHCP type */
177                 datatype = MAC_DATA_DHCP_ACK;
178             } else {
179                 datatype = MAC_DATA_BUTT;
180             }
181         }
182     }
183     return datatype;
184 }
185 
186 /* ****************************************************************************
187  功能描述  : 判断是否是DHCP6帧
188  修改历史      :
189   1.日    期   : 2014年8月7日
190     作    者   : HiSilicon
191     修改内容   : 新生成函数
192 **************************************************************************** */
mac_is_dhcp6(oal_ipv6hdr_stru * ipv6hdr)193 WIFI_ROM_TEXT hi_u8 mac_is_dhcp6(oal_ipv6hdr_stru *ipv6hdr)
194 {
195     udp_hdr_stru *udp_hdr = HI_NULL;
196 
197     if (ipv6hdr->nexthdr == MAC_UDP_PROTOCAL) {
198         udp_hdr = (udp_hdr_stru *)(ipv6hdr + 1);
199         if (udp_hdr->us_des_port == oal_host2net_short(MAC_IPV6_UDP_DES_PORT) ||
200             udp_hdr->us_des_port == oal_host2net_short(MAC_IPV6_UDP_SRC_PORT)) {
201             return HI_TRUE;
202         }
203     }
204     return HI_FALSE;
205 }
206 
mac_get_ipv6_data_type(oal_ipv6hdr_stru * ipv6)207 WIFI_ROM_TEXT static hi_u8 mac_get_ipv6_data_type(oal_ipv6hdr_stru *ipv6)
208 {
209     hi_u8 datatype = MAC_DATA_BUTT;
210 
211     if (mac_is_nd(ipv6)) {
212         datatype = MAC_DATA_ND;
213     } else if (mac_is_dhcp6(ipv6)) {
214         datatype = MAC_DATA_DHCPV6;
215 #ifdef _PRE_WLAN_FEATURE_MESH_ROM
216     } else if (mac_is_rpl(ipv6)) {
217         datatype = MAC_DATA_RPL;
218 #endif
219     }
220 
221     return datatype;
222 }
223 /* ****************************************************************************
224  功能描述  : 根据数据帧(802.3)的类型,判断帧类型
225  输入参数  : puc_frame_hdr: 为去除80211头的数据帧,可为以太头或snap头
226              uc_hdr_type: 指针指向数据类型,用来计算获取data_type时刻的偏移
227   1.日    期   : 2015年1月20日
228     作    者   : HiSilicon
229     修改内容   : 新生成函数
230 **************************************************************************** */
mac_get_data_type_from_8023(const hi_u8 * puc_frame_hdr,mac_netbuff_payload_type hdr_type)231 WIFI_ROM_TEXT hi_u8 mac_get_data_type_from_8023(const hi_u8 *puc_frame_hdr, mac_netbuff_payload_type hdr_type)
232 {
233     const hi_u8              *puc_frame_body = HI_NULL;
234     hi_u16              ether_type;
235     hi_u8               datatype = MAC_DATA_BUTT;
236 
237     if (puc_frame_hdr == HI_NULL) {
238         return datatype;
239     }
240     /* 偏移一个以太网头,取ip头 */
241     if (hdr_type == MAC_NETBUFF_PAYLOAD_ETH) {
242         ether_type = oal_net2host_short(((mac_ether_header_stru *)puc_frame_hdr)->us_ether_type);
243         puc_frame_body = puc_frame_hdr + (hi_u16)sizeof(mac_ether_header_stru);
244     } else if (hdr_type == MAC_NETBUFF_PAYLOAD_SNAP) {
245         ether_type = oal_net2host_short(((mac_llc_snap_stru *)puc_frame_hdr)->us_ether_type);
246         puc_frame_body = puc_frame_hdr + (hi_u16)sizeof(mac_llc_snap_stru);
247     } else {
248         return datatype;
249     }
250 
251     switch (ether_type) {
252         case ETHER_TYPE_IP:
253             datatype = mac_get_ipv4_data_type((mac_ip_header_stru *)puc_frame_body);
254             break;
255         case ETHER_TYPE_IPV6:
256             datatype = mac_get_ipv6_data_type((oal_ipv6hdr_stru *)puc_frame_body);
257             break;
258         case ETHER_TYPE_PAE:
259             datatype = MAC_DATA_EAPOL;
260             break;
261         /* TDLS帧处理,建链保护,入高优先级TID队列 */
262         case ETHER_TYPE_TDLS:
263             datatype = MAC_DATA_TDLS;
264             break;
265         /* PPPOE帧处理,建链保护(发现阶段, 会话阶段),入高优先级TID队列 */
266         case ETHER_TYPE_PPP_DISC:
267         case ETHER_TYPE_PPP_SES:
268             datatype = MAC_DATA_PPPOE;
269             break;
270         case ETHER_TYPE_WAI:
271             datatype = MAC_DATA_WAPI;
272             break;
273         case ETHER_TYPE_VLAN:
274             datatype = MAC_DATA_VLAN;
275             break;
276         case ETHER_TYPE_ARP:
277             /* 如果是ARP帧,则进入VO队列发送 */
278             datatype = mac_get_arp_type_by_arphdr((oal_eth_arphdr_stru *)puc_frame_body);
279             break;
280         /* _PRE_WLAN_FEATURE_MESH + */
281         case ETHER_TYPE_6LO:
282             datatype = MAC_DATA_6LO;
283             break;
284         default:
285             break;
286     }
287 
288     return datatype;
289 }
290 
291 /* 代码ROM段结束位置 新增ROM代码请放在SECTION中 */
292 #undef __WIFI_ROM_SECTION__
293 
294 #ifdef __cplusplus
295 #if __cplusplus
296 }
297 #endif
298 #endif
299