RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / include / proto / bcmproto.h
blob0902fb06bb49fda24ec7dab0d799a19aaab7aad7
1 /*
2 * Copyright (C) 2012, Broadcom Corporation. All Rights Reserved.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 * Fundamental constants relating to IP Protocol
18 * $Id: bcmproto.h 329791 2012-04-26 22:36:58Z $
21 #ifndef _bcmproto_h_
22 #define _bcmproto_h_
24 #ifndef _TYPEDEFS_H_
25 #include <typedefs.h>
26 #endif
28 enum frame_l2_hdr {
29 FRAME_L2_SNAP_H = 1,
30 FRAME_L2_SNAPVLAN_H,
31 FRAME_L2_ETH_H,
32 FRAME_L2_ETHVLAN_H,
33 FRAME_L2_ERROR,
36 enum frame_l3_hdr {
37 FRAME_L3_IP_H = 4,
38 FRAME_L3_IP6_H = 6,
39 FRAME_L3_ARP_H,
40 FRAME_L3_ERROR,
43 enum frame_l4_hdr {
44 FRAME_L4_ICMP_H = 1,
45 FRAME_L4_IGMP_H = 2,
46 FRAME_L4_TCP_H = 6,
47 FRAME_L4_UDP_H = 17,
48 FRAME_L4_ICMP6_H = 58,
49 FRAME_L4_ERROR,
52 typedef struct {
53 uint8 *l2;
54 uint8 l2_t;
55 uint16 l2_len;
56 uint8 *l3;
57 uint8 l3_t;
58 uint16 l3_len;
59 uint8 *l4;
60 uint8 l4_t;
61 uint16 l4_len;
62 } frame_proto_t;
64 static const uint8 llc_snap_hdr[SNAP_HDR_LEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
66 /* Generic header parser function */
67 static inline int
68 hnd_frame_proto(uint8 *p, int plen, frame_proto_t *fp)
70 struct dot3_mac_llc_snap_header *sh = (struct dot3_mac_llc_snap_header *)p;
71 struct dot3_mac_llc_snapvlan_header *svh = (struct dot3_mac_llc_snapvlan_header *)p;
72 struct ether_header *eh = (struct ether_header *)p;
73 struct ethervlan_header *evh = (struct ethervlan_header *)p;
74 uint16 type = ntoh16(eh->ether_type);
75 uint16 len;
77 if (p == NULL)
78 return BCME_ERROR;
80 bzero(fp, sizeof(frame_proto_t));
82 /* L2 header/pointer check */
83 fp->l2 = p;
84 fp->l2_len = plen;
85 if (type < ETHER_TYPE_MIN) {
86 if (bcmp(&sh->dsap, llc_snap_hdr, SNAP_HDR_LEN) == 0) {
87 type = ntoh16(sh->type);
88 if (type == ETHER_TYPE_8021Q) {
89 fp->l2_t = FRAME_L2_SNAP_H;
90 p += sizeof(struct dot3_mac_llc_snap_header);
91 if ((plen -= sizeof(struct dot3_mac_llc_snap_header)) < 0)
92 return BCME_ERROR;
94 else {
95 fp->l2_t = FRAME_L2_SNAPVLAN_H;
96 type = ntoh16(svh->ether_type);
97 p += sizeof(struct dot3_mac_llc_snapvlan_header);
98 if ((plen -= sizeof(struct dot3_mac_llc_snapvlan_header)) < 0)
99 return BCME_ERROR;
102 else
103 return BCME_ERROR;
105 else {
106 if (type == ETHER_TYPE_8021Q) {
107 fp->l2_t = FRAME_L2_ETHVLAN_H;
108 type = ntoh16(evh->ether_type);
109 p += ETHERVLAN_HDR_LEN;
110 if ((plen -= ETHERVLAN_HDR_LEN) < 0)
111 return BCME_ERROR;
113 else {
114 fp->l2_t = FRAME_L2_ETH_H;
115 p += ETHER_HDR_LEN;
116 if ((plen -= ETHER_HDR_LEN) < 0)
117 return BCME_ERROR;
120 /* L3 header/pointer check */
121 fp->l3 = p;
122 fp->l3_len = plen;
123 switch (type) {
124 case ETHER_TYPE_ARP: {
125 if ((plen -= ARP_DATA_LEN) < 0)
126 return BCME_ERROR;
128 fp->l3_t = FRAME_L3_ARP_H;
129 /* no layer 4 protocol, return */
130 return BCME_OK;
131 break;
133 case ETHER_TYPE_IP: {
134 struct ipv4_hdr *iph = (struct ipv4_hdr *)p;
135 len = IPV4_HLEN(iph);
137 if ((plen -= len) < 0)
138 return BCME_ERROR;
140 if (IP_VER(iph) == IP_VER_4 && len >= IPV4_MIN_HEADER_LEN) {
141 fp->l3_t = FRAME_L3_IP_H;
142 type = IPV4_PROT(iph);
143 p += len;
145 else /* not a valid ipv4 packet */
146 return BCME_ERROR;
147 break;
149 case ETHER_TYPE_IPV6: {
150 struct ipv6_hdr *ip6h = (struct ipv6_hdr *)p;
152 if ((plen -= IPV6_MIN_HLEN) < 0)
153 return BCME_ERROR;
155 if (IP_VER(ip6h) == IP_VER_6) {
156 fp->l3_t = FRAME_L3_IP6_H;
157 type = IPV6_PROT(ip6h);
158 p += IPV6_MIN_HLEN;
159 if (IPV6_EXTHDR(type)) {
160 /* only process tcp/udp case */
161 return BCME_ERROR;
164 else /* not a valid ipv6 packet */
165 return BCME_ERROR;
166 break;
168 default:
169 /* not interesting case */
170 return BCME_ERROR;
171 break;
174 /* L4 header/pointer check */
175 fp->l4 = p;
176 fp->l4_len = plen;
177 switch (type) {
178 case IP_PROT_ICMP:
179 fp->l4_t = FRAME_L4_ICMP_H;
180 break;
181 case IP_PROT_IGMP:
182 fp->l4_t = FRAME_L4_IGMP_H;
183 break;
184 case IP_PROT_TCP:
185 fp->l4_t = FRAME_L4_TCP_H;
186 break;
187 case IP_PROT_UDP:
188 fp->l4_t = FRAME_L4_UDP_H;
189 break;
190 case IP_PROT_ICMP6:
191 fp->l4_t = FRAME_L4_ICMP6_H;
192 break;
193 default:
194 break;
197 return BCME_OK;
200 #define FRAME_DROP 0
201 #define FRAME_NOP 1
202 #define FRAME_TAKEN 2
204 #endif /* _bcmproto_h_ */