suricata
decode-ipv4.h
Go to the documentation of this file.
1/* Copyright (C) 2007-2024 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 * \author Brian Rectanus <brectanu@gmail.com>
23 */
24
25#ifndef SURICATA_DECODE_IPV4_H
26#define SURICATA_DECODE_IPV4_H
27
28#define IPV4_HEADER_LEN 20 /**< Header length */
29#define IPV4_OPTMAX 40 /**< Max options length */
30#define IPV4_MAXPACKET_LEN 65535 /**< Maximum packet size */
31
32/** IP Option Types */
33#define IPV4_OPT_EOL 0x00 /**< Option: End of List */
34#define IPV4_OPT_NOP 0x01 /**< Option: No op */
35#define IPV4_OPT_RR 0x07 /**< Option: Record Route */
36#define IPV4_OPT_QS 0x19 /**< Option: Quick Start */
37#define IPV4_OPT_TS 0x44 /**< Option: Timestamp */
38#define IPV4_OPT_SEC 0x82 /**< Option: Security */
39#define IPV4_OPT_LSRR 0x83 /**< Option: Loose Source Route */
40#define IPV4_OPT_ESEC 0x85 /**< Option: Extended Security */
41#define IPV4_OPT_CIPSO 0x86 /**< Option: Commercial IP Security */
42#define IPV4_OPT_SID 0x88 /**< Option: Stream Identifier */
43#define IPV4_OPT_SSRR 0x89 /**< Option: Strict Source Route */
44#define IPV4_OPT_RTRALT 0x94 /**< Option: Router Alert */
45
46/** IP Option Lengths (fixed) */
47#define IPV4_OPT_SID_LEN 4 /**< SID Option Fixed Length */
48#define IPV4_OPT_RTRALT_LEN 4 /**< RTRALT Option Fixed Length */
49
50/** IP Option Lengths (variable) */
51#define IPV4_OPT_SEC_MIN 3 /**< SEC, ESEC Option Min Length */
52#define IPV4_OPT_ROUTE_MIN 3 /**< RR, SRR, LTRR Option Min Length */
53#define IPV4_OPT_QS_MIN 8 /**< QS Option Min Length */
54#define IPV4_OPT_TS_MIN 5 /**< TS Option Min Length */
55#define IPV4_OPT_CIPSO_MIN 10 /**< CIPSO Option Min Length */
56
57/** IP Option fields */
58#define IPV4_OPTS ip4vars.ip_opts
59#define IPV4_OPTS_CNT ip4vars.ip_opt_cnt
60
61typedef struct IPV4Opt_ {
62 /** \todo We may want to break type up into its 3 fields
63 * as the reassembler may want to know which options
64 * must be copied to each fragment.
65 */
66 uint8_t type; /**< option type */
67 uint8_t len; /**< option length (type+len+data) */
68 const uint8_t *data; /**< option data */
70
71typedef struct IPV4Hdr_
72{
73 uint8_t ip_verhl; /**< version & header length */
74 uint8_t ip_tos; /**< type of service */
75 uint16_t ip_len; /**< length */
76 uint16_t ip_id; /**< id */
77 uint16_t ip_off; /**< frag offset */
78 uint8_t ip_ttl; /**< time to live */
79 uint8_t ip_proto; /**< protocol (tcp, udp, etc) */
80 uint16_t ip_csum; /**< checksum */
81 union {
82 struct {
83 struct in_addr ip_src;/**< source address */
84 struct in_addr ip_dst;/**< destination address */
86 uint16_t ip_addrs[4];
89
90
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
94
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)
106
107/** return the raw (directly from the header) src ip as uint32_t */
108#define IPV4_GET_RAW_IPSRC_U32(ip4h) (uint32_t)((ip4h)->s_ip_src.s_addr)
109/** return the raw (directly from the header) dst ip as uint32_t */
110#define IPV4_GET_RAW_IPDST_U32(ip4h) (uint32_t)((ip4h)->s_ip_dst.s_addr)
111
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)
115
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)
128
129/* helper structure with parsed ipv4 info */
130typedef struct IPV4Vars_ {
131 uint16_t opt_cnt;
132 uint16_t opts_set;
134
135void DecodeIPV4RegisterTests(void);
136
137/** ----- Inline functions ----- */
138
139/**
140 * \brief Calculate or validate the checksum for the IP packet
141 *
142 * \param pkt Pointer to the start of the IP packet
143 * \param hlen Length of the IP header
144 * \param init The current checksum if validating, 0 if generating.
145 *
146 * \retval csum For validation 0 will be returned for success, for calculation
147 * this will be the checksum.
148 */
149static inline uint16_t IPV4Checksum(const uint16_t *pkt, uint16_t hlen, uint16_t init)
150{
151 uint32_t csum = init;
152
153 csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[6] + pkt[7] +
154 pkt[8] + pkt[9];
155
156 hlen -= 20;
157 pkt += 10;
158
159 if (hlen == 0) {
160 ;
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] +
169 pkt[7];
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] +
182 pkt[14] + pkt[15];
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];
191 }
192
193 csum = (csum >> 16) + (csum & 0x0000FFFF);
194 csum += (csum >> 16);
195
196 return (uint16_t) ~csum;
197}
198
199#endif /* SURICATA_DECODE_IPV4_H */
struct IPV4Hdr_ IPV4Hdr
void DecodeIPV4RegisterTests(void)
struct IPV4Vars_ IPV4Vars
struct IPV4Opt_ IPV4Opt
uint8_t ip_verhl
Definition decode-ipv4.h:73
struct IPV4Hdr_::@25::@26 ip4_un1
uint16_t ip_id
Definition decode-ipv4.h:76
struct in_addr ip_src
Definition decode-ipv4.h:83
uint8_t ip_tos
Definition decode-ipv4.h:74
uint16_t ip_off
Definition decode-ipv4.h:77
uint16_t ip_csum
Definition decode-ipv4.h:80
struct in_addr ip_dst
Definition decode-ipv4.h:84
uint8_t ip_proto
Definition decode-ipv4.h:79
uint8_t ip_ttl
Definition decode-ipv4.h:78
uint16_t ip_addrs[4]
Definition decode-ipv4.h:86
union IPV4Hdr_::@25 ip4_hdrun1
uint16_t ip_len
Definition decode-ipv4.h:75
uint8_t len
Definition decode-ipv4.h:67
const uint8_t * data
Definition decode-ipv4.h:68
uint8_t type
Definition decode-ipv4.h:66
uint16_t opt_cnt
uint16_t opts_set