summaryrefslogtreecommitdiffstats
path: root/src/common/include/proto/bcmip.h
blob: 50ce97dc04f2876a8d9d0d2efd9a1bbd9e6e96ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
 * 
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Fundamental constants relating to IP Protocol
 *
 * $Id: bcmip.h 329791 2012-04-26 22:36:58Z $
 */

#ifndef _bcmip_h_
#define _bcmip_h_

#ifndef _TYPEDEFS_H_
#include <typedefs.h>
#endif

#include <packed_section_start.h>

#define IP_VER_OFFSET		0x0	
#define IP_VER_MASK		0xf0	
#define IP_VER_SHIFT		4	
#define IP_VER_4		4	
#define IP_VER_6		6	

#define IP_VER(ip_body) \
	((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT)

#define IP_PROT_ICMP		0x1	
#define IP_PROT_IGMP		0x2	
#define IP_PROT_TCP		0x6	
#define IP_PROT_UDP		0x11	
#define IP_PROT_ICMP6		0x3a	

#define IPV4_VER_HL_OFFSET      0       
#define IPV4_TOS_OFFSET         1       
#define IPV4_PKTLEN_OFFSET      2       
#define IPV4_PKTFLAG_OFFSET     6       
#define IPV4_PROT_OFFSET        9       
#define IPV4_CHKSUM_OFFSET      10      
#define IPV4_SRC_IP_OFFSET      12      
#define IPV4_DEST_IP_OFFSET     16      
#define IPV4_OPTIONS_OFFSET     20      
#define IPV4_MIN_HEADER_LEN     20      

#define IPV4_VER_MASK		0xf0	
#define IPV4_VER_SHIFT		4	

#define IPV4_HLEN_MASK		0x0f	
#define IPV4_HLEN(ipv4_body)	(4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK))

#define IPV4_ADDR_LEN		4	

#define IPV4_ADDR_NULL(a)	((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \
				  ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0)

#define IPV4_ADDR_BCAST(a)	((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \
				  ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff)

#define	IPV4_TOS_DSCP_MASK	0xfc	
#define	IPV4_TOS_DSCP_SHIFT	2	

#define	IPV4_TOS(ipv4_body)	(((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET])

#define	IPV4_TOS_PREC_MASK	0xe0	
#define	IPV4_TOS_PREC_SHIFT	5	

#define IPV4_TOS_LOWDELAY	0x10	
#define IPV4_TOS_THROUGHPUT	0x8	
#define IPV4_TOS_RELIABILITY	0x4	

#define IPV4_PROT(ipv4_body)	(((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET])

#define IPV4_FRAG_RESV		0x8000	
#define IPV4_FRAG_DONT		0x4000	
#define IPV4_FRAG_MORE		0x2000	
#define IPV4_FRAG_OFFSET_MASK	0x1fff	

#define IPV4_ADDR_STR_LEN	16	

BWL_PRE_PACKED_STRUCT struct ipv4_addr {
	uint8	addr[IPV4_ADDR_LEN];
} BWL_POST_PACKED_STRUCT;

BWL_PRE_PACKED_STRUCT struct ipv4_hdr {
	uint8	version_ihl;		
	uint8	tos;			
	uint16	tot_len;		
	uint16	id;
	uint16	frag;			
	uint8	ttl;			
	uint8	prot;			
	uint16	hdr_chksum;		
	uint8	src_ip[IPV4_ADDR_LEN];	
	uint8	dst_ip[IPV4_ADDR_LEN];	
} BWL_POST_PACKED_STRUCT;

#define IPV6_PAYLOAD_LEN_OFFSET	4	
#define IPV6_NEXT_HDR_OFFSET	6	
#define IPV6_HOP_LIMIT_OFFSET	7	
#define IPV6_SRC_IP_OFFSET	8	
#define IPV6_DEST_IP_OFFSET	24	

#define IPV6_TRAFFIC_CLASS(ipv6_body) \
	(((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \
	 ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4))

#define IPV6_FLOW_LABEL(ipv6_body) \
	(((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \
	 (((uint8 *)(ipv6_body))[2] << 8) | \
	 (((uint8 *)(ipv6_body))[3]))

#define IPV6_PAYLOAD_LEN(ipv6_body) \
	((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \
	 ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1])

#define IPV6_NEXT_HDR(ipv6_body) \
	(((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET])

#define IPV6_PROT(ipv6_body)	IPV6_NEXT_HDR(ipv6_body)

#define IPV6_ADDR_LEN		16	

#define IP_TOS46(ip_body) \
	(IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \
	 IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0)

#define IPV6_EXTHDR_HOP		0
#define IPV6_EXTHDR_ROUTING	43
#define IPV6_EXTHDR_FRAGMENT	44
#define IPV6_EXTHDR_AUTH	51
#define IPV6_EXTHDR_NONE	59
#define IPV6_EXTHDR_DEST	60

#define IPV6_EXTHDR(prot)	(((prot) == IPV6_EXTHDR_HOP) || \
	                         ((prot) == IPV6_EXTHDR_ROUTING) || \
	                         ((prot) == IPV6_EXTHDR_FRAGMENT) || \
	                         ((prot) == IPV6_EXTHDR_AUTH) || \
	                         ((prot) == IPV6_EXTHDR_NONE) || \
	                         ((prot) == IPV6_EXTHDR_DEST))

#define IPV6_MIN_HLEN 		40

#define IPV6_EXTHDR_LEN(eh)	((((struct ipv6_exthdr *)(eh))->hdrlen + 1) << 3)

BWL_PRE_PACKED_STRUCT struct ipv6_exthdr {
	uint8	nexthdr;
	uint8	hdrlen;
} BWL_POST_PACKED_STRUCT;

BWL_PRE_PACKED_STRUCT struct ipv6_exthdr_frag {
	uint8	nexthdr;
	uint8	rsvd;
	uint16	frag_off;
	uint32	ident;
} BWL_POST_PACKED_STRUCT;

static INLINE int32
ipv6_exthdr_len(uint8 *h, uint8 *proto)
{
	uint16 len = 0, hlen;
	struct ipv6_exthdr *eh = (struct ipv6_exthdr *)h;

	while (IPV6_EXTHDR(eh->nexthdr)) {
		if (eh->nexthdr == IPV6_EXTHDR_NONE)
			return -1;
		else if (eh->nexthdr == IPV6_EXTHDR_FRAGMENT)
			hlen = 8;
		else if (eh->nexthdr == IPV6_EXTHDR_AUTH)
			hlen = (eh->hdrlen + 2) << 2;
		else
			hlen = IPV6_EXTHDR_LEN(eh);

		len += hlen;
		eh = (struct ipv6_exthdr *)(h + len);
	}

	*proto = eh->nexthdr;
	return len;
}

#define IPV4_ISMULTI(a) (((a) & 0xf0000000) == 0xe0000000)

#include <packed_section_end.h>

#endif