suricata
decode-ipv6.h
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 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  */
23 
24 #ifndef __DECODE_IPV6_H__
25 #define __DECODE_IPV6_H__
26 
27 #define IPV6_HEADER_LEN 40
28 #define IPV6_MAXPACKET 65535 /* maximum packet size */
29 #define IPV6_MAX_OPT 40
30 
31 typedef struct IPV6Hdr_
32 {
33  union {
34  struct ip6_un1_ {
35  uint32_t ip6_un1_flow; /* 20 bits of flow-ID */
36  uint16_t ip6_un1_plen; /* payload length */
37  uint8_t ip6_un1_nxt; /* next header */
38  uint8_t ip6_un1_hlim; /* hop limit */
39  } ip6_un1;
40  uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */
41  } ip6_hdrun;
42 
43  union {
44  struct {
45  uint32_t ip6_src[4];
46  uint32_t ip6_dst[4];
47  } ip6_un2;
48  uint16_t ip6_addrs[16];
49  } ip6_hdrun2;
50 } IPV6Hdr;
51 
52 #define s_ip6_src ip6_hdrun2.ip6_un2.ip6_src
53 #define s_ip6_dst ip6_hdrun2.ip6_un2.ip6_dst
54 #define s_ip6_addrs ip6_hdrun2.ip6_addrs
55 
56 #define s_ip6_vfc ip6_hdrun.ip6_un2_vfc
57 #define s_ip6_flow ip6_hdrun.ip6_un1.ip6_un1_flow
58 #define s_ip6_plen ip6_hdrun.ip6_un1.ip6_un1_plen
59 #define s_ip6_nxt ip6_hdrun.ip6_un1.ip6_un1_nxt
60 #define s_ip6_hlim ip6_hdrun.ip6_un1.ip6_un1_hlim
61 
62 #define IPV6_GET_RAW_VER(ip6h) (((ip6h)->s_ip6_vfc & 0xf0) >> 4)
63 #define IPV6_GET_RAW_CLASS(ip6h) ((SCNtohl((ip6h)->s_ip6_flow) & 0x0FF00000) >> 20)
64 #define IPV6_GET_RAW_FLOW(ip6h) (SCNtohl((ip6h)->s_ip6_flow) & 0x000FFFFF)
65 #define IPV6_GET_RAW_NH(ip6h) ((ip6h)->s_ip6_nxt)
66 #define IPV6_GET_RAW_PLEN(ip6h) (SCNtohs((ip6h)->s_ip6_plen))
67 #define IPV6_GET_RAW_HLIM(ip6h) ((ip6h)->s_ip6_hlim)
68 
69 #define IPV6_SET_RAW_VER(ip6h, value) ((ip6h)->s_ip6_vfc = (((ip6h)->s_ip6_vfc & 0x0f) | (value << 4)))
70 #define IPV6_SET_RAW_NH(ip6h, value) ((ip6h)->s_ip6_nxt = (value))
71 
72 #define IPV6_SET_L4PROTO(p,proto) (p)->ip6vars.l4proto = proto
73 
74 
75 /* ONLY call these functions after making sure that:
76  * 1. p->ip6h is set
77  * 2. p->ip6h is valid (len is correct)
78  */
79 #define IPV6_GET_VER(p) \
80  IPV6_GET_RAW_VER((p)->ip6h)
81 #define IPV6_GET_CLASS(p) \
82  IPV6_GET_RAW_CLASS((p)->ip6h)
83 #define IPV6_GET_FLOW(p) \
84  IPV6_GET_RAW_FLOW((p)->ip6h)
85 #define IPV6_GET_NH(p) \
86  (IPV6_GET_RAW_NH((p)->ip6h))
87 #define IPV6_GET_PLEN(p) \
88  IPV6_GET_RAW_PLEN((p)->ip6h)
89 #define IPV6_GET_HLIM(p) \
90  (IPV6_GET_RAW_HLIM((p)->ip6h))
91 /* XXX */
92 #define IPV6_GET_L4PROTO(p) \
93  ((p)->ip6vars.l4proto)
94 
95 /** \brief get the highest proto/next header field we know */
96 //#define IPV6_GET_UPPER_PROTO(p) (p)->ip6eh.ip6_exthdrs_cnt ?
97 // (p)->ip6eh.ip6_exthdrs[(p)->ip6eh.ip6_exthdrs_cnt - 1].next : IPV6_GET_NH((p))
98 
99 /* helper structure with parsed ipv6 info */
100 typedef struct IPV6Vars_
101 {
102  uint8_t ip_opts_len;
103  uint8_t l4proto; /* the proto after the extension headers
104  * store while decoding so we don't have
105  * to loop through the exthdrs all the time */
106 } IPV6Vars;
107 
108 #define CLEAR_IPV6_PACKET(p) do { \
109  (p)->ip6h = NULL; \
110  (p)->ip6vars.ip_opts_len = 0; \
111  (p)->ip6vars.l4proto = 0; \
112  memset(&(p)->ip6eh, 0x00, sizeof((p)->ip6eh)); \
113 } while (0)
114 
115 /* Fragment header */
116 typedef struct IPV6FragHdr_
117 {
118  uint8_t ip6fh_nxt; /* next header */
119  uint8_t ip6fh_reserved; /* reserved field */
120  uint16_t ip6fh_offlg; /* offset, reserved, and flag */
121  uint32_t ip6fh_ident; /* identification */
122 } __attribute__((__packed__)) IPV6FragHdr;
123 
124 #define IPV6_EXTHDR_GET_FH_NH(p) (p)->ip6eh.fh_nh
125 #define IPV6_EXTHDR_GET_FH_OFFSET(p) (p)->ip6eh.fh_offset
126 #define IPV6_EXTHDR_GET_FH_FLAG(p) (p)->ip6eh.fh_more_frags_set
127 #define IPV6_EXTHDR_GET_FH_ID(p) (p)->ip6eh.fh_id
128 
129 /* rfc 1826 */
130 typedef struct IPV6AuthHdr_
131 {
132  uint8_t ip6ah_nxt; /* next header */
133  uint8_t ip6ah_len; /* header length in units of 8 bytes, not
134  including first 8 bytes. */
135  uint16_t ip6ah_reserved; /* reserved for future use */
136  uint32_t ip6ah_spi; /* SECURITY PARAMETERS INDEX (SPI) */
137  uint32_t ip6ah_seq; /* sequence number */
138 } __attribute__((__packed__)) IPV6AuthHdr;
139 
140 typedef struct IPV6EspHdr_
141 {
142  uint32_t ip6esph_spi; /* SECURITY PARAMETERS INDEX (SPI) */
143  uint32_t ip6esph_seq; /* sequence number */
144 } __attribute__((__packed__)) IPV6EspHdr;
145 
146 typedef struct IPV6RouteHdr_
147 {
148  uint8_t ip6rh_nxt; /* next header */
149  uint8_t ip6rh_len; /* header length in units of 8 bytes, not
150  including first 8 bytes. */
151  uint8_t ip6rh_type; /* routing type */
152  uint8_t ip6rh_segsleft; /* segments left */
153 } __attribute__((__packed__)) IPV6RouteHdr;
154 
155 
156 /* Hop-by-Hop header and Destination Options header use options that are
157  * defined here. */
158 
159 #define IPV6OPT_PAD1 0x00
160 #define IPV6OPT_PADN 0x01
161 #define IPV6OPT_RA 0x05
162 #define IPV6OPT_JUMBO 0xC2
163 #define IPV6OPT_HAO 0xC9
164 
165 /* Home Address Option */
166 typedef struct IPV6OptHAO_
167 {
168  uint8_t ip6hao_type; /* Option type */
169  uint8_t ip6hao_len; /* Option Data len (excludes type and len) */
170  struct in6_addr ip6hao_hoa; /* Home address. */
171 } IPV6OptHAO;
172 
173 /* Router Alert Option */
174 typedef struct IPV6OptRA_
175 {
176  uint8_t ip6ra_type; /* Option type */
177  uint8_t ip6ra_len; /* Option Data len (excludes type and len) */
178  uint16_t ip6ra_value; /* Router Alert value */
179 } IPV6OptRA;
180 
181 /* Jumbo Option */
182 typedef struct IPV6OptJumbo_
183 {
184  uint8_t ip6j_type; /* Option type */
185  uint8_t ip6j_len; /* Option Data len (excludes type and len) */
186  uint32_t ip6j_payload_len; /* Jumbo Payload Length */
187 } IPV6OptJumbo;
188 
189 typedef struct IPV6HopOptsHdr_
190 {
191  uint8_t ip6hh_nxt; /* next header */
192  uint8_t ip6hh_len; /* header length in units of 8 bytes, not
193  including first 8 bytes. */
194 } __attribute__((__packed__)) IPV6HopOptsHdr;
195 
196 typedef struct IPV6DstOptsHdr_
197 {
198  uint8_t ip6dh_nxt; /* next header */
199  uint8_t ip6dh_len; /* header length in units of 8 bytes, not
200  including first 8 bytes. */
201 } __attribute__((__packed__)) IPV6DstOptsHdr;
202 
203 typedef struct IPV6GenOptHdr_
204 {
205  uint8_t type;
206  uint8_t next;
207  uint8_t len;
208  uint8_t *data;
209 } IPV6GenOptHdr;
210 
211 typedef struct IPV6ExtHdrs_
212 {
213  _Bool rh_set;
214  uint8_t rh_type;
215 
216  _Bool fh_set;
218  uint8_t fh_nh;
219 
220  uint8_t fh_prev_nh;
222 
224  uint16_t fh_data_offset;
225  uint16_t fh_data_len;
226 
227  /* In fh_offset we store the offset of this extension into the packet past
228  * the ipv6 header. We use it in defrag for creating a defragmented packet
229  * without the frag header */
230  uint16_t fh_offset;
231  uint32_t fh_id;
232 
233 } IPV6ExtHdrs;
234 
235 #define IPV6_EXTHDR_SET_FH(p) (p)->ip6eh.fh_set = TRUE
236 #define IPV6_EXTHDR_ISSET_FH(p) (p)->ip6eh.fh_set
237 #define IPV6_EXTHDR_SET_RH(p) (p)->ip6eh.rh_set = TRUE
238 #define IPV6_EXTHDR_ISSET_RH(p) (p)->ip6eh.rh_set
239 
240 void DecodeIPV6RegisterTests(void);
241 
242 #endif /* __DECODE_IPV6_H__ */
243 
uint8_t ip6rh_nxt
Definition: decode-ipv6.h:148
union IPV6Hdr_::@37 ip6_hdrun
uint8_t ip6hao_len
Definition: decode-ipv6.h:169
uint8_t ip6_un1_nxt
Definition: decode-ipv6.h:37
uint8_t ip6hh_len
Definition: decode-ipv6.h:192
void DecodeIPV6RegisterTests(void)
this function registers unit tests for IPV6 decoder
Definition: decode-ipv6.c:924
uint32_t ip6esph_spi
Definition: decode-ipv6.h:142
struct IPV6OptHAO_ IPV6OptHAO
uint8_t ip6ah_nxt
Definition: decode-ipv6.h:132
struct IPV6Hdr_::@37::ip6_un1_ ip6_un1
uint8_t ip_opts_len
Definition: decode-ipv6.h:102
uint16_t ip6_addrs[16]
Definition: decode-ipv6.h:48
struct IPV6OptJumbo_ IPV6OptJumbo
uint8_t ip6dh_len
Definition: decode-ipv6.h:199
uint32_t ip6esph_seq
Definition: decode-ipv6.h:143
uint8_t ip6fh_nxt
Definition: decode-ipv6.h:118
uint8_t ip6fh_reserved
Definition: decode-ipv6.h:119
uint32_t ip6fh_ident
Definition: decode-ipv6.h:121
struct IPV6GenOptHdr_ IPV6GenOptHdr
uint8_t ip6rh_len
Definition: decode-ipv6.h:149
uint8_t ip6ra_type
Definition: decode-ipv6.h:176
uint16_t ip6ah_reserved
Definition: decode-ipv6.h:135
uint32_t ip6_dst[4]
Definition: decode-ipv6.h:46
struct IPV6Hdr_::@38::@39 ip6_un2
uint8_t ip6hh_nxt
Definition: decode-ipv6.h:191
uint16_t ip6fh_offlg
Definition: decode-ipv6.h:120
uint16_t fh_data_len
Definition: decode-ipv6.h:225
uint8_t fh_nh
Definition: decode-ipv6.h:218
uint16_t ip6ra_value
Definition: decode-ipv6.h:178
uint16_t fh_header_offset
Definition: decode-ipv6.h:223
struct IPV6Hdr_ IPV6Hdr
uint32_t ip6ah_seq
Definition: decode-ipv6.h:137
uint8_t fh_prev_nh
Definition: decode-ipv6.h:220
uint8_t ip6_un1_hlim
Definition: decode-ipv6.h:38
uint8_t ip6j_len
Definition: decode-ipv6.h:185
uint8_t ip6dh_nxt
Definition: decode-ipv6.h:198
uint32_t ip6_un1_flow
Definition: decode-ipv6.h:35
uint32_t ip6_src[4]
Definition: decode-ipv6.h:45
uint8_t ip6j_type
Definition: decode-ipv6.h:184
_Bool fh_more_frags_set
Definition: decode-ipv6.h:217
uint32_t ip6ah_spi
Definition: decode-ipv6.h:136
uint16_t ip6_un1_plen
Definition: decode-ipv6.h:36
uint8_t ip6ah_len
Definition: decode-ipv6.h:133
struct IPV6OptRA_ IPV6OptRA
uint8_t rh_type
Definition: decode-ipv6.h:214
struct IPV6ExtHdrs_ IPV6ExtHdrs
get the highest proto/next header field we know
Definition: decode-ipv6.h:100
uint32_t ip6j_payload_len
Definition: decode-ipv6.h:186
union IPV6Hdr_::@38 ip6_hdrun2
uint8_t ip6hao_type
Definition: decode-ipv6.h:168
struct IPV6Vars_ IPV6Vars
get the highest proto/next header field we know
uint16_t fh_offset
Definition: decode-ipv6.h:230
uint8_t ip6rh_type
Definition: decode-ipv6.h:151
uint16_t fh_data_offset
Definition: decode-ipv6.h:224
uint8_t ip6rh_segsleft
Definition: decode-ipv6.h:152
uint16_t fh_prev_hdr_offset
Definition: decode-ipv6.h:221
uint8_t ip6ra_len
Definition: decode-ipv6.h:177
uint32_t fh_id
Definition: decode-ipv6.h:231
uint8_t ip6_un2_vfc
Definition: decode-ipv6.h:40
uint8_t * data
Definition: decode-ipv6.h:208
struct IPV6FragHdr_ __attribute__((__packed__)) IPV6FragHdr
DNP3 link header.
uint8_t l4proto
Definition: decode-ipv6.h:103