25 #ifndef SURICATA_DECODE_IPV4_H
26 #define SURICATA_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_ESEC 0x85
41 #define IPV4_OPT_CIPSO 0x86
42 #define IPV4_OPT_SID 0x88
43 #define IPV4_OPT_SSRR 0x89
44 #define IPV4_OPT_RTRALT 0x94
47 #define IPV4_OPT_SID_LEN 4
48 #define IPV4_OPT_RTRALT_LEN 4
51 #define IPV4_OPT_SEC_MIN 3
52 #define IPV4_OPT_ROUTE_MIN 3
53 #define IPV4_OPT_QS_MIN 8
54 #define IPV4_OPT_TS_MIN 5
55 #define IPV4_OPT_CIPSO_MIN 10
58 #define IPV4_OPTS ip4vars.ip_opts
59 #define IPV4_OPTS_CNT ip4vars.ip_opt_cnt
91 #define s_ip_src ip4_hdrun1.ip4_un1.ip_src
92 #define s_ip_dst ip4_hdrun1.ip4_un1.ip_dst
93 #define s_ip_addrs ip4_hdrun1.ip_addrs
95 #define IPV4_GET_RAW_VER(ip4h) (((ip4h)->ip_verhl & 0xf0) >> 4)
96 #define IPV4_GET_RAW_HLEN(ip4h) (uint8_t)(((ip4h)->ip_verhl & (uint8_t)0x0f) << (uint8_t)2)
97 #define IPV4_GET_RAW_IPTOS(ip4h) ((ip4h)->ip_tos)
98 #define IPV4_GET_RAW_IPLEN(ip4h) (SCNtohs((ip4h)->ip_len))
99 #define IPV4_GET_RAW_IPID(ip4h) (SCNtohs((ip4h)->ip_id))
100 #define IPV4_GET_RAW_IPOFFSET(ip4h) SCNtohs((ip4h)->ip_off)
101 #define IPV4_GET_RAW_FRAGOFFSET(ip4h) (IPV4_GET_RAW_IPOFFSET((ip4h)) & 0x1fff)
102 #define IPV4_GET_RAW_IPTTL(ip4h) ((ip4h)->ip_ttl)
103 #define IPV4_GET_RAW_IPPROTO(ip4h) ((ip4h)->ip_proto)
104 #define IPV4_GET_RAW_IPSRC(ip4h) ((ip4h)->s_ip_src)
105 #define IPV4_GET_RAW_IPDST(ip4h) ((ip4h)->s_ip_dst)
108 #define IPV4_GET_RAW_IPSRC_U32(ip4h) (uint32_t)((ip4h)->s_ip_src.s_addr)
110 #define IPV4_GET_RAW_IPDST_U32(ip4h) (uint32_t)((ip4h)->s_ip_dst.s_addr)
112 #define IPV4_GET_RAW_FLAG_MF(ip4h) ((IPV4_GET_RAW_IPOFFSET((ip4h)) & 0x2000) != 0)
113 #define IPV4_GET_RAW_FLAG_DF(ip4h) ((IPV4_GET_RAW_IPOFFSET((ip4h)) & 0x4000) != 0)
114 #define IPV4_GET_RAW_FLAG_RF(ip4h) ((IPV4_GET_RAW_IPOFFSET((ip4h)) & 0x8000) != 0)
116 #define IPV4_OPT_FLAG_EOL BIT_U16(1)
117 #define IPV4_OPT_FLAG_NOP BIT_U16(2)
118 #define IPV4_OPT_FLAG_RR BIT_U16(3)
119 #define IPV4_OPT_FLAG_TS BIT_U16(4)
120 #define IPV4_OPT_FLAG_QS BIT_U16(5)
121 #define IPV4_OPT_FLAG_LSRR BIT_U16(6)
122 #define IPV4_OPT_FLAG_SSRR BIT_U16(7)
123 #define IPV4_OPT_FLAG_SID BIT_U16(8)
124 #define IPV4_OPT_FLAG_SEC BIT_U16(9)
125 #define IPV4_OPT_FLAG_CIPSO BIT_U16(10)
126 #define IPV4_OPT_FLAG_RTRALT BIT_U16(11)
127 #define IPV4_OPT_FLAG_ESEC BIT_U16(12)
149 static inline uint16_t IPV4Checksum(
const uint16_t *pkt, uint16_t hlen, uint16_t init)
151 uint32_t csum = init;
153 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[6] + pkt[7] +
161 }
else if (hlen == 4) {
162 csum += pkt[0] + pkt[1];
163 }
else if (hlen == 8) {
164 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3];
165 }
else if (hlen == 12) {
166 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5];
167 }
else if (hlen == 16) {
168 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
170 }
else if (hlen == 20) {
171 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
172 pkt[7] + pkt[8] + pkt[9];
173 }
else if (hlen == 24) {
174 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
175 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11];
176 }
else if (hlen == 28) {
177 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
178 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13];
179 }
else if (hlen == 32) {
180 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
181 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] +
183 }
else if (hlen == 36) {
184 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
185 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] +
186 pkt[14] + pkt[15] + pkt[16] + pkt[17];
187 }
else if (hlen == 40) {
188 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] +
189 pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] +
190 pkt[14] + pkt[15] + pkt[16] + pkt[17] + pkt[18] + pkt[19];
193 csum = (csum >> 16) + (csum & 0x0000FFFF);
194 csum += (csum >> 16);
196 return (uint16_t) ~csum;