25 #ifndef __DECODE_IPV4_H__
26 #define __DECODE_IPV4_H__
28 #define IPV4_HEADER_LEN 20
29 #define IPV4_OPTMAX 40
30 #define IPV4_MAXPACKET_LEN 65535
33 #define IPV4_OPT_EOL 0x00
34 #define IPV4_OPT_NOP 0x01
35 #define IPV4_OPT_RR 0x07
36 #define IPV4_OPT_QS 0x19
37 #define IPV4_OPT_TS 0x44
38 #define IPV4_OPT_SEC 0x82
39 #define IPV4_OPT_LSRR 0x83
40 #define IPV4_OPT_CIPSO 0x86
41 #define IPV4_OPT_SID 0x88
42 #define IPV4_OPT_SSRR 0x89
43 #define IPV4_OPT_RTRALT 0x94
46 #define IPV4_OPT_SEC_LEN 11
47 #define IPV4_OPT_SID_LEN 4
48 #define IPV4_OPT_RTRALT_LEN 4
51 #define IPV4_OPT_ROUTE_MIN 3
52 #define IPV4_OPT_QS_MIN 8
53 #define IPV4_OPT_TS_MIN 5
54 #define IPV4_OPT_CIPSO_MIN 10
57 #define IPV4_OPTS ip4vars.ip_opts
58 #define IPV4_OPTS_CNT ip4vars.ip_opt_cnt
90 #define s_ip_src ip4_hdrun1.ip4_un1.ip_src
91 #define s_ip_dst ip4_hdrun1.ip4_un1.ip_dst
92 #define s_ip_addrs ip4_hdrun1.ip_addrs
94 #define IPV4_GET_RAW_VER(ip4h) (((ip4h)->ip_verhl & 0xf0) >> 4)
95 #define IPV4_GET_RAW_HLEN(ip4h) ((ip4h)->ip_verhl & 0x0f)
96 #define IPV4_GET_RAW_IPTOS(ip4h) ((ip4h)->ip_tos)
97 #define IPV4_GET_RAW_IPLEN(ip4h) ((ip4h)->ip_len)
98 #define IPV4_GET_RAW_IPID(ip4h) ((ip4h)->ip_id)
99 #define IPV4_GET_RAW_IPOFFSET(ip4h) ((ip4h)->ip_off)
100 #define IPV4_GET_RAW_IPTTL(ip4h) ((ip4h)->ip_ttl)
101 #define IPV4_GET_RAW_IPPROTO(ip4h) ((ip4h)->ip_proto)
102 #define IPV4_GET_RAW_IPSRC(ip4h) ((ip4h)->s_ip_src)
103 #define IPV4_GET_RAW_IPDST(ip4h) ((ip4h)->s_ip_dst)
106 #define IPV4_GET_RAW_IPSRC_U32(ip4h) (uint32_t)((ip4h)->s_ip_src.s_addr)
108 #define IPV4_GET_RAW_IPDST_U32(ip4h) (uint32_t)((ip4h)->s_ip_dst.s_addr)
111 #define IPV4_SET_RAW_VER(ip4h, value) ((ip4h)->ip_verhl = (((ip4h)->ip_verhl & 0x0f) | (value << 4)))
112 #define IPV4_SET_RAW_HLEN(ip4h, value) ((ip4h)->ip_verhl = (((ip4h)->ip_verhl & 0xf0) | (value & 0x0f)))
113 #define IPV4_SET_RAW_IPTOS(ip4h, value) ((ip4h)->ip_tos = value)
114 #define IPV4_SET_RAW_IPLEN(ip4h, value) ((ip4h)->ip_len = value)
115 #define IPV4_SET_RAW_IPPROTO(ip4h, value) ((ip4h)->ip_proto = value)
121 #define IPV4_GET_VER(p) \
122 IPV4_GET_RAW_VER((p)->ip4h)
123 #define IPV4_GET_HLEN(p) ((uint8_t)(IPV4_GET_RAW_HLEN((p)->ip4h) << 2))
124 #define IPV4_GET_IPTOS(p) \
125 IPV4_GET_RAW_IPTOS((p)->ip4h)
126 #define IPV4_GET_IPLEN(p) \
127 (SCNtohs(IPV4_GET_RAW_IPLEN((p)->ip4h)))
128 #define IPV4_GET_IPID(p) \
129 (SCNtohs(IPV4_GET_RAW_IPID((p)->ip4h)))
131 #define _IPV4_GET_IPOFFSET(p) \
132 (SCNtohs(IPV4_GET_RAW_IPOFFSET((p)->ip4h)))
134 #define IPV4_GET_IPOFFSET(p) \
135 (_IPV4_GET_IPOFFSET(p) & 0x1fff)
137 #define IPV4_GET_RF(p) \
138 (uint8_t)((_IPV4_GET_IPOFFSET((p)) & 0x8000) >> 15)
140 #define IPV4_GET_DF(p) \
141 (uint8_t)((_IPV4_GET_IPOFFSET((p)) & 0x4000) >> 14)
143 #define IPV4_GET_MF(p) \
144 (uint8_t)((_IPV4_GET_IPOFFSET((p)) & 0x2000) >> 13)
145 #define IPV4_GET_IPTTL(p) \
146 IPV4_GET_RAW_IPTTL(p->ip4h)
147 #define IPV4_GET_IPPROTO(p) \
148 IPV4_GET_RAW_IPPROTO((p)->ip4h)
150 #define CLEAR_IPV4_PACKET(p) do { \
152 (p)->level3_comp_csum = -1; \
153 memset(&p->ip4vars, 0x00, sizeof(p->ip4vars)); \
194 static inline uint16_t IPV4Checksum(
const uint16_t *pkt, uint16_t hlen, uint16_t init)
196 uint32_t csum = init;
198 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[6] + pkt[7] +
206 }
else if (hlen == 4) {
207 csum += pkt[0] + pkt[1];
208 }
else if (hlen == 8) {
209 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3];
210 }
else if (hlen == 12) {
211 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5];
212 }
else if (hlen == 16) {
213 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
215 }
else if (hlen == 20) {
216 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
217 pkt[7] + pkt[8] + pkt[9];
218 }
else if (hlen == 24) {
219 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
220 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11];
221 }
else if (hlen == 28) {
222 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
223 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13];
224 }
else if (hlen == 32) {
225 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
226 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] +
228 }
else if (hlen == 36) {
229 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
230 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] +
231 pkt[14] + pkt[15] + pkt[16] + pkt[17];
232 }
else if (hlen == 40) {
233 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
234 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] +
235 pkt[14] + pkt[15] + pkt[16] + pkt[17] + pkt[18] + pkt[19];
238 csum = (csum >> 16) + (csum & 0x0000FFFF);
239 csum += (csum >> 16);
241 return (uint16_t) ~csum;