]>
Commit | Line | Data |
---|---|---|
2eef905c | 1 | /* Copyright (C) 2007-2010 Open Information Security Foundation |
ce019275 WM |
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 | ||
acf10525 EL |
18 | /** |
19 | * \ingroup decode | |
20 | * | |
21 | * @{ | |
22 | */ | |
23 | ||
24 | ||
ce019275 WM |
25 | /** |
26 | * \file | |
27 | * | |
28 | * \author Victor Julien <victor@inliniac.net> | |
29 | * | |
30 | * Decode ICMPv6 | |
31 | */ | |
bab4b623 | 32 | |
ecf86f9c | 33 | #include "suricata-common.h" |
bab4b623 | 34 | #include "decode-icmpv6.h" |
292a7e47 PR |
35 | #include "decode.h" |
36 | #include "decode-tcp.h" | |
8be92fdd | 37 | #include "decode-sctp.h" |
292a7e47 PR |
38 | #include "decode-udp.h" |
39 | #include "decode-events.h" | |
401a0313 | 40 | #include "util-unittest.h" |
292a7e47 | 41 | #include "flow.h" |
3a28171f | 42 | #include "util-debug.h" |
6b9d1012 | 43 | #include "util-print.h" |
401a0313 | 44 | |
c5bd04f1 EL |
45 | #include "pkt-var.h" |
46 | #include "util-profiling.h" | |
47 | #include "host.h" | |
48 | ||
292a7e47 PR |
49 | |
50 | /** | |
51 | * \brief Get variables and do some checks of the embedded IPV6 packet | |
52 | * | |
53 | * \param p Pointer to the packet we are filling | |
54 | * \param partial_packet Pointer to the raw packet buffer | |
55 | * \param len the len of the rest of the packet not processed yet | |
56 | * | |
57 | * \retval void No return value | |
58 | */ | |
ab1200fb | 59 | static void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len ) |
292a7e47 PR |
60 | { |
61 | /** Check the sizes, the header must fit at least */ | |
62 | if (len < IPV6_HEADER_LEN) { | |
06c382a4 | 63 | SCLogDebug("ICMPV6_IPV6_TRUNC_PKT"); |
b2c58b8d | 64 | ENGINE_SET_INVALID_EVENT(p, ICMPV6_IPV6_TRUNC_PKT); |
292a7e47 PR |
65 | return; |
66 | } | |
67 | ||
68 | IPV6Hdr *icmp6_ip6h = (IPV6Hdr*)partial_packet; | |
69 | ||
70 | /** Check the embedded version */ | |
71 | if(((icmp6_ip6h->s_ip6_vfc & 0xf0) >> 4) != 6) | |
32830ff4 | 72 | { |
06c382a4 | 73 | SCLogDebug("ICMPv6 contains Unknown IPV6 version " |
32830ff4 | 74 | "ICMPV6_IPV6_UNKNOWN_VER"); |
b2c58b8d | 75 | ENGINE_SET_INVALID_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER); |
292a7e47 PR |
76 | return; |
77 | } | |
78 | ||
79 | /** We need to fill icmpv6vars */ | |
80 | p->icmpv6vars.emb_ipv6h = icmp6_ip6h; | |
81 | ||
82 | /** Get the IP6 address */ | |
cdba2f50 VJ |
83 | p->icmpv6vars.emb_ip6_src[0] = icmp6_ip6h->s_ip6_src[0]; |
84 | p->icmpv6vars.emb_ip6_src[1] = icmp6_ip6h->s_ip6_src[1]; | |
85 | p->icmpv6vars.emb_ip6_src[2] = icmp6_ip6h->s_ip6_src[2]; | |
86 | p->icmpv6vars.emb_ip6_src[3] = icmp6_ip6h->s_ip6_src[3]; | |
292a7e47 | 87 | |
cdba2f50 VJ |
88 | p->icmpv6vars.emb_ip6_dst[0] = icmp6_ip6h->s_ip6_dst[0]; |
89 | p->icmpv6vars.emb_ip6_dst[1] = icmp6_ip6h->s_ip6_dst[1]; | |
90 | p->icmpv6vars.emb_ip6_dst[2] = icmp6_ip6h->s_ip6_dst[2]; | |
91 | p->icmpv6vars.emb_ip6_dst[3] = icmp6_ip6h->s_ip6_dst[3]; | |
292a7e47 PR |
92 | |
93 | /** Get protocol and ports inside the embedded ipv6 packet and set the pointers */ | |
94 | p->icmpv6vars.emb_ip6_proto_next = icmp6_ip6h->s_ip6_nxt; | |
95 | ||
96 | switch (icmp6_ip6h->s_ip6_nxt) { | |
97 | case IPPROTO_TCP: | |
98 | if (len >= IPV6_HEADER_LEN + TCP_HEADER_LEN ) { | |
99 | p->icmpv6vars.emb_tcph = (TCPHdr*)(partial_packet + IPV6_HEADER_LEN); | |
100 | p->icmpv6vars.emb_sport = p->icmpv6vars.emb_tcph->th_sport; | |
101 | p->icmpv6vars.emb_dport = p->icmpv6vars.emb_tcph->th_dport; | |
102 | ||
06c382a4 | 103 | SCLogDebug("ICMPV6->IPV6->TCP header sport: " |
248f9c66 | 104 | "%"PRIu16" dport %"PRIu16"", p->icmpv6vars.emb_sport, |
292a7e47 PR |
105 | p->icmpv6vars.emb_dport); |
106 | } else { | |
06c382a4 | 107 | SCLogDebug("Warning, ICMPV6->IPV6->TCP " |
292a7e47 PR |
108 | "header Didn't fit in the packet!"); |
109 | p->icmpv6vars.emb_sport = 0; | |
110 | p->icmpv6vars.emb_dport = 0; | |
111 | } | |
112 | ||
113 | break; | |
114 | case IPPROTO_UDP: | |
115 | if (len >= IPV6_HEADER_LEN + UDP_HEADER_LEN ) { | |
116 | p->icmpv6vars.emb_udph = (UDPHdr*)(partial_packet + IPV6_HEADER_LEN); | |
117 | p->icmpv6vars.emb_sport = p->icmpv6vars.emb_udph->uh_sport; | |
118 | p->icmpv6vars.emb_dport = p->icmpv6vars.emb_udph->uh_dport; | |
119 | ||
06c382a4 | 120 | SCLogDebug("ICMPV6->IPV6->UDP header sport: " |
248f9c66 | 121 | "%"PRIu16" dport %"PRIu16"", p->icmpv6vars.emb_sport, |
292a7e47 PR |
122 | p->icmpv6vars.emb_dport); |
123 | } else { | |
06c382a4 | 124 | SCLogDebug("Warning, ICMPV6->IPV6->UDP " |
292a7e47 PR |
125 | "header Didn't fit in the packet!"); |
126 | p->icmpv6vars.emb_sport = 0; | |
127 | p->icmpv6vars.emb_dport = 0; | |
128 | } | |
129 | ||
130 | break; | |
131 | case IPPROTO_ICMPV6: | |
132 | p->icmpv6vars.emb_icmpv6h = (ICMPV6Hdr*)(partial_packet + IPV6_HEADER_LEN); | |
133 | p->icmpv6vars.emb_sport = 0; | |
134 | p->icmpv6vars.emb_dport = 0; | |
135 | ||
06c382a4 | 136 | SCLogDebug("ICMPV6->IPV6->ICMP header"); |
292a7e47 PR |
137 | |
138 | break; | |
139 | } | |
140 | ||
141 | /* debug print */ | |
142 | #ifdef DEBUG | |
143 | char s[46], d[46]; | |
6b9d1012 EL |
144 | PrintInet(AF_INET6, (const void *)p->icmpv6vars.emb_ip6_src, s, sizeof(s)); |
145 | PrintInet(AF_INET6, (const void *)p->icmpv6vars.emb_ip6_dst, d, sizeof(d)); | |
292a7e47 PR |
146 | SCLogDebug("ICMPv6 embedding IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: " |
147 | "%" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32, | |
148 | s, d, IPV6_GET_RAW_CLASS(icmp6_ip6h), IPV6_GET_RAW_FLOW(icmp6_ip6h), | |
149 | IPV6_GET_RAW_NH(icmp6_ip6h), IPV6_GET_RAW_PLEN(icmp6_ip6h), IPV6_GET_RAW_HLIM(icmp6_ip6h)); | |
150 | #endif | |
151 | ||
152 | return; | |
153 | } | |
154 | ||
c662383b VJ |
155 | /** \retval type counterpart type or -1 */ |
156 | int ICMPv6GetCounterpart(uint8_t type) | |
157 | { | |
158 | #define CASE_CODE(t,r) case (t): return r; case (r): return t; | |
159 | switch (type) { | |
160 | CASE_CODE(ICMP6_ECHO_REQUEST, ICMP6_ECHO_REPLY); | |
161 | CASE_CODE(ND_NEIGHBOR_SOLICIT, ND_NEIGHBOR_ADVERT); | |
162 | CASE_CODE(ND_ROUTER_SOLICIT, ND_ROUTER_ADVERT); | |
163 | CASE_CODE(MLD_LISTENER_QUERY, MLD_LISTENER_REPORT); | |
164 | CASE_CODE(ICMP6_NI_QUERY, ICMP6_NI_REPLY); | |
165 | CASE_CODE(HOME_AGENT_AD_REQUEST,HOME_AGENT_AD_REPLY); | |
166 | ||
167 | CASE_CODE(MOBILE_PREFIX_SOLICIT,MOBILE_PREFIX_ADVERT); | |
168 | CASE_CODE(CERT_PATH_SOLICIT, CERT_PATH_ADVERT); | |
169 | CASE_CODE(MC_ROUTER_ADVERT, MC_ROUTER_SOLICIT); | |
170 | CASE_CODE(DUPL_ADDR_REQUEST, DUPL_ADDR_CONFIRM); | |
171 | default: | |
172 | return -1; | |
173 | } | |
174 | #undef CASE_CODE | |
175 | } | |
176 | ||
292a7e47 PR |
177 | /** |
178 | * \brief Decode ICMPV6 packets and fill the Packet with the decoded info | |
179 | * | |
180 | * \param tv Pointer to the thread variables | |
181 | * \param dtv Pointer to the decode thread variables | |
182 | * \param p Pointer to the packet we are filling | |
183 | * \param pkt Pointer to the raw packet buffer | |
184 | * \param len the len of the rest of the packet not processed yet | |
292a7e47 PR |
185 | * |
186 | * \retval void No return value | |
187 | */ | |
d4b7ecfb | 188 | int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, |
f8aed4ce | 189 | const uint8_t *pkt, uint32_t len) |
bab4b623 | 190 | { |
ba367dad | 191 | int full_hdr = 0; |
1c0b4ee0 | 192 | StatsIncr(tv, dtv->counter_icmpv6); |
d0e70309 | 193 | |
bab4b623 | 194 | if (len < ICMPV6_HEADER_LEN) { |
06c382a4 | 195 | SCLogDebug("ICMPV6_PKT_TOO_SMALL"); |
b2c58b8d | 196 | ENGINE_SET_INVALID_EVENT(p, ICMPV6_PKT_TOO_SMALL); |
d4b7ecfb | 197 | return TM_ECODE_FAILED; |
bab4b623 VJ |
198 | } |
199 | ||
57f71f7e | 200 | p->icmpv6h = (ICMPV6Hdr *)pkt; |
292a7e47 | 201 | p->proto = IPPROTO_ICMPV6; |
c662383b VJ |
202 | p->icmp_s.type = p->icmpv6h->type; |
203 | p->icmp_s.code = p->icmpv6h->code; | |
ad9ec4db | 204 | p->payload_len = len - ICMPV6_HEADER_LEN; |
579cc9f0 | 205 | p->payload = (uint8_t *)pkt + ICMPV6_HEADER_LEN; |
57f71f7e | 206 | |
c662383b VJ |
207 | int ctype = ICMPv6GetCounterpart(p->icmp_s.type); |
208 | if (ctype != -1) { | |
209 | p->icmp_d.type = (uint8_t)ctype; | |
210 | } | |
211 | ||
292a7e47 PR |
212 | SCLogDebug("ICMPV6 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv6h->type, |
213 | p->icmpv6h->code); | |
214 | ||
215 | switch (ICMPV6_GET_TYPE(p)) { | |
216 | case ICMP6_DST_UNREACH: | |
06c382a4 | 217 | SCLogDebug("ICMP6_DST_UNREACH"); |
292a7e47 PR |
218 | |
219 | if (ICMPV6_GET_CODE(p) > ICMP6_DST_UNREACH_REJECTROUTE) { | |
7425bf5c | 220 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
292a7e47 | 221 | } else { |
55b14f37 MA |
222 | if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) { |
223 | return TM_ECODE_FAILED; | |
224 | } | |
292a7e47 PR |
225 | DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN), |
226 | len - ICMPV6_HEADER_LEN ); | |
ba367dad | 227 | full_hdr = 1; |
292a7e47 PR |
228 | } |
229 | ||
230 | break; | |
231 | case ICMP6_PACKET_TOO_BIG: | |
06c382a4 | 232 | SCLogDebug("ICMP6_PACKET_TOO_BIG"); |
292a7e47 PR |
233 | |
234 | if (ICMPV6_GET_CODE(p) != 0) { | |
7425bf5c | 235 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
292a7e47 | 236 | } else { |
55b14f37 MA |
237 | if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) { |
238 | return TM_ECODE_FAILED; | |
239 | } | |
292a7e47 PR |
240 | p->icmpv6vars.mtu = ICMPV6_GET_MTU(p); |
241 | DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN), | |
242 | len - ICMPV6_HEADER_LEN ); | |
ba367dad | 243 | full_hdr = 1; |
292a7e47 PR |
244 | } |
245 | ||
246 | break; | |
247 | case ICMP6_TIME_EXCEEDED: | |
06c382a4 | 248 | SCLogDebug("ICMP6_TIME_EXCEEDED"); |
292a7e47 PR |
249 | |
250 | if (ICMPV6_GET_CODE(p) > ICMP6_TIME_EXCEED_REASSEMBLY) { | |
7425bf5c | 251 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
292a7e47 | 252 | } else { |
55b14f37 MA |
253 | if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) { |
254 | return TM_ECODE_FAILED; | |
255 | } | |
292a7e47 PR |
256 | DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN), |
257 | len - ICMPV6_HEADER_LEN ); | |
ba367dad | 258 | full_hdr = 1; |
292a7e47 PR |
259 | } |
260 | ||
261 | break; | |
262 | case ICMP6_PARAM_PROB: | |
06c382a4 | 263 | SCLogDebug("ICMP6_PARAM_PROB"); |
292a7e47 PR |
264 | |
265 | if (ICMPV6_GET_CODE(p) > ICMP6_PARAMPROB_OPTION) { | |
7425bf5c | 266 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
292a7e47 | 267 | } else { |
55b14f37 MA |
268 | if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) { |
269 | return TM_ECODE_FAILED; | |
270 | } | |
292a7e47 PR |
271 | p->icmpv6vars.error_ptr= ICMPV6_GET_ERROR_PTR(p); |
272 | DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN), | |
273 | len - ICMPV6_HEADER_LEN ); | |
ba367dad | 274 | full_hdr = 1; |
292a7e47 PR |
275 | } |
276 | ||
277 | break; | |
278 | case ICMP6_ECHO_REQUEST: | |
06c382a4 | 279 | SCLogDebug("ICMP6_ECHO_REQUEST id: %u seq: %u", |
7e87f373 | 280 | p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq); |
292a7e47 PR |
281 | |
282 | if (ICMPV6_GET_CODE(p) != 0) { | |
7425bf5c | 283 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
292a7e47 | 284 | } else { |
7e87f373 GIG |
285 | p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id; |
286 | p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq; | |
ba367dad | 287 | full_hdr = 1; |
292a7e47 PR |
288 | } |
289 | ||
290 | break; | |
291 | case ICMP6_ECHO_REPLY: | |
06c382a4 | 292 | SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u", |
7e87f373 | 293 | p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq); |
292a7e47 | 294 | |
98e8b13b | 295 | if (ICMPV6_GET_CODE(p) != 0) { |
7425bf5c | 296 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
292a7e47 | 297 | } else { |
7e87f373 GIG |
298 | p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id; |
299 | p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq; | |
ba367dad | 300 | full_hdr = 1; |
292a7e47 PR |
301 | } |
302 | ||
7a9da787 JI |
303 | break; |
304 | case ND_ROUTER_SOLICIT: | |
305 | SCLogDebug("ND_ROUTER_SOLICIT"); | |
98e8b13b | 306 | if (ICMPV6_GET_CODE(p) != 0) { |
9f2ce16e VJ |
307 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
308 | } | |
309 | break; | |
7a9da787 JI |
310 | case ND_ROUTER_ADVERT: |
311 | SCLogDebug("ND_ROUTER_ADVERT"); | |
98e8b13b | 312 | if (ICMPV6_GET_CODE(p) != 0) { |
9f2ce16e VJ |
313 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
314 | } | |
315 | break; | |
7a9da787 JI |
316 | case ND_NEIGHBOR_SOLICIT: |
317 | SCLogDebug("ND_NEIGHBOR_SOLICIT"); | |
98e8b13b | 318 | if (ICMPV6_GET_CODE(p) != 0) { |
9f2ce16e VJ |
319 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
320 | } | |
321 | break; | |
7a9da787 JI |
322 | case ND_NEIGHBOR_ADVERT: |
323 | SCLogDebug("ND_NEIGHBOR_ADVERT"); | |
98e8b13b | 324 | if (ICMPV6_GET_CODE(p) != 0) { |
9f2ce16e VJ |
325 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
326 | } | |
327 | break; | |
7a9da787 JI |
328 | case ND_REDIRECT: |
329 | SCLogDebug("ND_REDIRECT"); | |
98e8b13b | 330 | if (ICMPV6_GET_CODE(p) != 0) { |
7a9da787 JI |
331 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
332 | } | |
292a7e47 | 333 | break; |
7539372d VJ |
334 | case MLD_LISTENER_QUERY: |
335 | SCLogDebug("MLD_LISTENER_QUERY"); | |
98e8b13b | 336 | if (ICMPV6_GET_CODE(p) != 0) { |
7539372d VJ |
337 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
338 | } | |
0bb2b154 VJ |
339 | if (IPV6_GET_HLIM(p) != 1) { |
340 | ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); | |
341 | } | |
7539372d VJ |
342 | break; |
343 | case MLD_LISTENER_REPORT: | |
344 | SCLogDebug("MLD_LISTENER_REPORT"); | |
98e8b13b | 345 | if (ICMPV6_GET_CODE(p) != 0) { |
7539372d VJ |
346 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
347 | } | |
0bb2b154 VJ |
348 | if (IPV6_GET_HLIM(p) != 1) { |
349 | ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); | |
350 | } | |
7539372d VJ |
351 | break; |
352 | case MLD_LISTENER_REDUCTION: | |
353 | SCLogDebug("MLD_LISTENER_REDUCTION"); | |
98e8b13b | 354 | if (ICMPV6_GET_CODE(p) != 0) { |
7539372d VJ |
355 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); |
356 | } | |
0bb2b154 VJ |
357 | if (IPV6_GET_HLIM(p) != 1) { |
358 | ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); | |
359 | } | |
7539372d | 360 | break; |
98e8b13b AH |
361 | case ICMP6_RR: |
362 | SCLogDebug("ICMP6_RR"); | |
363 | if (ICMPV6_GET_CODE(p) > 2 && ICMPV6_GET_CODE(p) != 255) { | |
364 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
365 | } | |
366 | break; | |
367 | case ICMP6_NI_QUERY: | |
368 | SCLogDebug("ICMP6_NI_QUERY"); | |
369 | if (ICMPV6_GET_CODE(p) > 2) { | |
370 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
371 | } | |
372 | break; | |
373 | case ICMP6_NI_REPLY: | |
374 | SCLogDebug("ICMP6_NI_REPLY"); | |
375 | if (ICMPV6_GET_CODE(p) > 2) { | |
376 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
377 | } | |
378 | break; | |
379 | case ND_INVERSE_SOLICIT: | |
380 | SCLogDebug("ND_INVERSE_SOLICIT"); | |
381 | if (ICMPV6_GET_CODE(p) != 0) { | |
382 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
383 | } | |
384 | break; | |
385 | case ND_INVERSE_ADVERT: | |
386 | SCLogDebug("ND_INVERSE_ADVERT"); | |
387 | if (ICMPV6_GET_CODE(p) != 0) { | |
388 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
389 | } | |
390 | break; | |
391 | case MLD_V2_LIST_REPORT: | |
392 | SCLogDebug("MLD_V2_LIST_REPORT"); | |
393 | if (ICMPV6_GET_CODE(p) != 0) { | |
394 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
395 | } | |
396 | break; | |
397 | case HOME_AGENT_AD_REQUEST: | |
398 | SCLogDebug("HOME_AGENT_AD_REQUEST"); | |
399 | if (ICMPV6_GET_CODE(p) != 0) { | |
400 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
401 | } | |
402 | break; | |
403 | case HOME_AGENT_AD_REPLY: | |
404 | SCLogDebug("HOME_AGENT_AD_REPLY"); | |
405 | if (ICMPV6_GET_CODE(p) != 0) { | |
406 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
407 | } | |
408 | break; | |
409 | case MOBILE_PREFIX_SOLICIT: | |
410 | SCLogDebug("MOBILE_PREFIX_SOLICIT"); | |
411 | if (ICMPV6_GET_CODE(p) != 0) { | |
412 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
413 | } | |
414 | break; | |
415 | case MOBILE_PREFIX_ADVERT: | |
416 | SCLogDebug("MOBILE_PREFIX_ADVERT"); | |
417 | if (ICMPV6_GET_CODE(p) != 0) { | |
418 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
419 | } | |
420 | break; | |
421 | case CERT_PATH_SOLICIT: | |
422 | SCLogDebug("CERT_PATH_SOLICIT"); | |
423 | if (ICMPV6_GET_CODE(p) != 0) { | |
424 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
425 | } | |
426 | break; | |
427 | case CERT_PATH_ADVERT: | |
428 | SCLogDebug("CERT_PATH_ADVERT"); | |
429 | if (ICMPV6_GET_CODE(p) != 0) { | |
430 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
431 | } | |
432 | break; | |
433 | case ICMP6_MOBILE_EXPERIMENTAL: | |
434 | SCLogDebug("ICMP6_MOBILE_EXPERIMENTAL"); | |
435 | break; | |
436 | case MC_ROUTER_ADVERT: | |
437 | SCLogDebug("MC_ROUTER_ADVERT"); | |
438 | break; | |
439 | case MC_ROUTER_SOLICIT: | |
440 | SCLogDebug("MC_ROUTER_SOLICIT"); | |
441 | break; | |
442 | case MC_ROUTER_TERMINATE: | |
443 | SCLogDebug("MC_ROUTER_TERMINATE"); | |
444 | break; | |
445 | case FMIPV6_MSG: | |
446 | SCLogDebug("FMIPV6_MSG"); | |
447 | if (ICMPV6_GET_CODE(p) != 0) { | |
448 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
449 | } | |
450 | break; | |
451 | case RPL_CONTROL_MSG: | |
452 | SCLogDebug("RPL_CONTROL_MSG"); | |
453 | if (ICMPV6_GET_CODE(p) > 3 && ICMPV6_GET_CODE(p) < 128) { | |
454 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
455 | } | |
456 | if (ICMPV6_GET_CODE(p) > 132) { | |
457 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
458 | } | |
459 | break; | |
460 | case LOCATOR_UDATE_MSG: | |
461 | SCLogDebug("LOCATOR_UDATE_MSG"); | |
462 | if (ICMPV6_GET_CODE(p) != 0) { | |
463 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
464 | } | |
465 | break; | |
466 | case DUPL_ADDR_REQUEST: | |
467 | SCLogDebug("DUPL_ADDR_REQUEST"); | |
468 | if (ICMPV6_GET_CODE(p) != 0) { | |
469 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
470 | } | |
471 | break; | |
472 | case DUPL_ADDR_CONFIRM: | |
473 | SCLogDebug("DUPL_ADDR_CONFIRM"); | |
474 | if (ICMPV6_GET_CODE(p) != 0) { | |
475 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
476 | } | |
477 | break; | |
478 | case MPL_CONTROL_MSG: | |
479 | SCLogDebug("MPL_CONTROL_MSG"); | |
480 | if (ICMPV6_GET_CODE(p) != 0) { | |
481 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); | |
482 | } | |
483 | break; | |
292a7e47 | 484 | default: |
ab3aed7d EL |
485 | /* Various range taken from: |
486 | * http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-2 | |
487 | */ | |
488 | if ((ICMPV6_GET_TYPE(p) > 4) && (ICMPV6_GET_TYPE(p) < 100)) { | |
489 | ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE); | |
490 | } else if ((ICMPV6_GET_TYPE(p) >= 100) && (ICMPV6_GET_TYPE(p) < 102)) { | |
491 | ENGINE_SET_EVENT(p, ICMPV6_EXPERIMENTATION_TYPE); | |
492 | } else if ((ICMPV6_GET_TYPE(p) >= 102) && (ICMPV6_GET_TYPE(p) < 127)) { | |
493 | ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE); | |
494 | } else if ((ICMPV6_GET_TYPE(p) >= 160) && (ICMPV6_GET_TYPE(p) < 200)) { | |
495 | ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE); | |
496 | } else if ((ICMPV6_GET_TYPE(p) >= 200) && (ICMPV6_GET_TYPE(p) < 202)) { | |
497 | ENGINE_SET_EVENT(p, ICMPV6_EXPERIMENTATION_TYPE); | |
498 | } else if (ICMPV6_GET_TYPE(p) >= 202) { | |
499 | ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE); | |
500 | } else { | |
501 | SCLogDebug("ICMPV6 Message type %" PRIu8 " not " | |
502 | "implemented yet", ICMPV6_GET_TYPE(p)); | |
503 | ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_TYPE); | |
504 | } | |
292a7e47 PR |
505 | } |
506 | ||
a6471cdb | 507 | /* for a info message the header is just 4 bytes */ |
ba367dad | 508 | if (!full_hdr) { |
a6471cdb VJ |
509 | if (p->payload_len >= 4) { |
510 | p->payload_len -= 4; | |
579cc9f0 | 511 | p->payload = (uint8_t *)pkt + 4; |
a6471cdb VJ |
512 | } else { |
513 | p->payload_len = 0; | |
514 | p->payload = NULL; | |
515 | } | |
516 | } | |
292a7e47 | 517 | |
a6471cdb | 518 | #ifdef DEBUG |
7425bf5c | 519 | if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) |
06c382a4 | 520 | SCLogDebug("Unknown Code, ICMPV6_UNKNOWN_CODE"); |
292a7e47 | 521 | |
7425bf5c | 522 | if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_TYPE)) |
06c382a4 | 523 | SCLogDebug("Unknown Type, ICMPV6_UNKNOWN_TYPE"); |
a6471cdb | 524 | #endif |
bab4b623 | 525 | |
2f0e0f17 | 526 | FlowSetupPacket(p); |
10cc9d5b | 527 | |
d4b7ecfb | 528 | return TM_ECODE_OK; |
bab4b623 VJ |
529 | } |
530 | ||
c43319c3 BS |
531 | #ifdef UNITTESTS |
532 | ||
8f1d7503 KS |
533 | static int ICMPV6CalculateValidChecksumtest01(void) |
534 | { | |
401a0313 AS |
535 | uint16_t csum = 0; |
536 | ||
537 | uint8_t raw_ipv6[] = { | |
538 | 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60, | |
539 | 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00, | |
540 | 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe, | |
541 | 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, | |
542 | 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe, | |
543 | 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, | |
544 | 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00, | |
545 | 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, | |
546 | 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe, | |
547 | 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, | |
548 | 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, | |
549 | 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, | |
550 | 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, | |
551 | 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01, | |
552 | 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed, | |
553 | 0x08, 0x00}; | |
554 | ||
555 | csum = *( ((uint16_t *)(raw_ipv6 + 56))); | |
556 | ||
3cf8b462 | 557 | FAIL_IF(csum != ICMPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), |
401a0313 | 558 | (uint16_t *)(raw_ipv6 + 54), 68)); |
3cf8b462 | 559 | PASS; |
401a0313 AS |
560 | } |
561 | ||
8f1d7503 KS |
562 | static int ICMPV6CalculateInvalidChecksumtest02(void) |
563 | { | |
401a0313 AS |
564 | uint16_t csum = 0; |
565 | ||
566 | uint8_t raw_ipv6[] = { | |
567 | 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60, | |
568 | 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00, | |
569 | 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe, | |
570 | 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, | |
571 | 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe, | |
572 | 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, | |
573 | 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00, | |
574 | 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, | |
575 | 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe, | |
576 | 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, | |
577 | 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, | |
578 | 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, | |
579 | 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, | |
580 | 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01, | |
581 | 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed, | |
582 | 0x08, 0x01}; | |
583 | ||
584 | csum = *( ((uint16_t *)(raw_ipv6 + 56))); | |
585 | ||
3cf8b462 | 586 | FAIL_IF(csum == ICMPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), |
401a0313 | 587 | (uint16_t *)(raw_ipv6 + 54), 68)); |
3cf8b462 | 588 | PASS; |
401a0313 AS |
589 | } |
590 | ||
292a7e47 PR |
591 | /** \test icmpv6 message type: parameter problem, valid packet |
592 | * | |
593 | * \retval retval 0 = Error ; 1 = ok | |
594 | */ | |
595 | static int ICMPV6ParamProbTest01(void) | |
596 | { | |
292a7e47 PR |
597 | static uint8_t raw_ipv6[] = { |
598 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, | |
599 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
600 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
601 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
602 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
603 | 0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf, | |
604 | 0x69, 0x70, 0x12, 0xb7, 0x00, 0x08, 0x3a, 0xff, | |
605 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
606 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
607 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
608 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
609 | 0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40 }; | |
610 | ||
1db4aadd | 611 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 612 | FAIL_IF_NULL(p); |
292a7e47 PR |
613 | IPV6Hdr ip6h; |
614 | ThreadVars tv; | |
615 | DecodeThreadVars dtv; | |
616 | uint32_t *ipv6src; | |
617 | uint32_t *ipv6dst; | |
618 | ipv6src = (uint32_t*) &raw_ipv6[8]; | |
619 | ipv6dst = (uint32_t*) &raw_ipv6[24]; | |
620 | ||
621 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 622 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
623 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
624 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
625 | ||
626 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 627 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 628 | |
3cf8b462 | 629 | FAIL_IF(p->icmpv6h == NULL); |
292a7e47 | 630 | |
3cf8b462 JI |
631 | /* ICMPv6 not processed at all? */ |
632 | FAIL_IF(ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0 || | |
633 | ICMPV6_GET_EMB_PROTO(p) != IPPROTO_ICMPV6); | |
292a7e47 PR |
634 | |
635 | /* Let's check if we retrieved the embedded ipv6 addresses correctly */ | |
636 | uint32_t i=0; | |
637 | for (i = 0; i < 4; i++) { | |
3cf8b462 JI |
638 | FAIL_IF(p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] || |
639 | p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]); | |
292a7e47 PR |
640 | } |
641 | ||
c5bd04f1 EL |
642 | PACKET_RECYCLE(p); |
643 | FlowShutdown(); | |
1db4aadd | 644 | SCFree(p); |
3cf8b462 | 645 | PASS; |
292a7e47 PR |
646 | } |
647 | ||
648 | /** \test icmpv6 message type: packet too big, valid packet | |
649 | * | |
650 | * \retval retval 0 = Error ; 1 = ok | |
651 | */ | |
652 | static int ICMPV6PktTooBigTest01(void) | |
653 | { | |
292a7e47 PR |
654 | static uint8_t raw_ipv6[] = { |
655 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, | |
656 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
657 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
658 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
659 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
660 | 0x02, 0x00, 0x5c, 0x7a, 0x00, 0x00, 0x05, 0x00, | |
661 | 0x64, 0x14, 0xfd, 0xff, 0x00, 0x00, 0x3b, 0xff, | |
662 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
663 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
664 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
665 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; | |
666 | ||
1db4aadd | 667 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 668 | FAIL_IF_NULL(p); |
292a7e47 PR |
669 | IPV6Hdr ip6h; |
670 | ThreadVars tv; | |
671 | DecodeThreadVars dtv; | |
672 | uint32_t *ipv6src; | |
673 | uint32_t *ipv6dst; | |
674 | ipv6src = (uint32_t*) &raw_ipv6[8]; | |
675 | ipv6dst = (uint32_t*) &raw_ipv6[24]; | |
676 | ||
677 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 678 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
679 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
680 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
681 | ||
682 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 683 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 684 | |
3cf8b462 | 685 | FAIL_IF(p->icmpv6h == NULL); |
292a7e47 | 686 | |
3cf8b462 JI |
687 | /* Note: it has an embedded ipv6 packet but no protocol after ipv6 |
688 | * (IPPROTO_NONE) */ | |
689 | /* Check if ICMPv6 header was processed at all. */ | |
690 | FAIL_IF(ICMPV6_GET_TYPE(p) != 2 || ICMPV6_GET_CODE(p) != 0 ); | |
292a7e47 PR |
691 | |
692 | /* Let's check if we retrieved the embedded ipv6 addresses correctly */ | |
693 | uint32_t i=0; | |
694 | for (i = 0; i < 4; i++) { | |
3cf8b462 JI |
695 | FAIL_IF(p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] || |
696 | p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]); | |
292a7e47 PR |
697 | } |
698 | ||
699 | SCLogDebug("ICMPV6 IPV6 src and dst properly set"); | |
700 | ||
c5bd04f1 EL |
701 | PACKET_RECYCLE(p); |
702 | FlowShutdown(); | |
1db4aadd | 703 | SCFree(p); |
3cf8b462 | 704 | PASS; |
292a7e47 PR |
705 | } |
706 | ||
707 | /** \test icmpv6 message type: time exceed, valid packet | |
708 | * | |
709 | * \retval retval 0 = Error ; 1 = ok | |
710 | */ | |
711 | static int ICMPV6TimeExceedTest01(void) | |
712 | { | |
292a7e47 PR |
713 | static uint8_t raw_ipv6[] = { |
714 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, | |
715 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
716 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
717 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
718 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
719 | 0x03, 0x00, 0x56, 0x2d, 0x00, 0x00, 0x00, 0x00, | |
720 | 0x6d, 0x23, 0xff, 0x3d, 0x00, 0x00, 0x3b, 0xff, | |
721 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
722 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
723 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
724 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; | |
725 | ||
1db4aadd | 726 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 727 | FAIL_IF_NULL(p); |
292a7e47 PR |
728 | IPV6Hdr ip6h; |
729 | ThreadVars tv; | |
730 | DecodeThreadVars dtv; | |
731 | uint32_t *ipv6src; | |
732 | uint32_t *ipv6dst; | |
733 | ipv6src = (uint32_t*) &raw_ipv6[8]; | |
734 | ipv6dst = (uint32_t*) &raw_ipv6[24]; | |
735 | ||
292a7e47 | 736 | memset(&tv, 0, sizeof(ThreadVars)); |
1db4aadd | 737 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
738 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
739 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
740 | ||
741 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 742 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 743 | |
3cf8b462 | 744 | FAIL_IF_NULL(p->icmpv6h); |
292a7e47 PR |
745 | |
746 | /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */ | |
3cf8b462 JI |
747 | FAIL_IF(ICMPV6_GET_TYPE(p) != 3 || ICMPV6_GET_CODE(p) != 0 || |
748 | ICMPV6_GET_EMB_IPV6(p) == NULL || | |
749 | ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE); | |
292a7e47 PR |
750 | |
751 | /* Let's check if we retrieved the embedded ipv6 addresses correctly */ | |
752 | uint32_t i=0; | |
753 | for (i = 0; i < 4; i++) { | |
3cf8b462 JI |
754 | FAIL_IF(p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] || |
755 | p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]); | |
292a7e47 PR |
756 | } |
757 | ||
758 | SCLogDebug("ICMPV6 IPV6 src and dst properly set"); | |
759 | ||
c5bd04f1 EL |
760 | PACKET_RECYCLE(p); |
761 | FlowShutdown(); | |
1db4aadd | 762 | SCFree(p); |
3cf8b462 | 763 | PASS; |
292a7e47 PR |
764 | } |
765 | ||
766 | /** \test icmpv6 message type: destination unreach, valid packet | |
767 | * | |
768 | * \retval retval 0 = Error ; 1 = ok | |
769 | */ | |
770 | static int ICMPV6DestUnreachTest01(void) | |
771 | { | |
292a7e47 PR |
772 | static uint8_t raw_ipv6[] = { |
773 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, | |
774 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
775 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
776 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
777 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
778 | 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, | |
779 | 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, | |
780 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
781 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
782 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
783 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; | |
784 | ||
1db4aadd | 785 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 786 | FAIL_IF_NULL(p); |
292a7e47 PR |
787 | IPV6Hdr ip6h; |
788 | ThreadVars tv; | |
789 | DecodeThreadVars dtv; | |
790 | uint32_t *ipv6src; | |
791 | uint32_t *ipv6dst; | |
792 | ipv6src = (uint32_t*) &raw_ipv6[8]; | |
793 | ipv6dst = (uint32_t*) &raw_ipv6[24]; | |
794 | ||
292a7e47 | 795 | memset(&tv, 0, sizeof(ThreadVars)); |
1db4aadd | 796 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
797 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
798 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
799 | ||
800 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 801 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 802 | |
3cf8b462 | 803 | FAIL_IF_NULL(p->icmpv6h); |
292a7e47 PR |
804 | |
805 | /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */ | |
3cf8b462 JI |
806 | FAIL_IF(ICMPV6_GET_TYPE(p) != 1 || ICMPV6_GET_CODE(p) != 0 || |
807 | ICMPV6_GET_EMB_IPV6(p) == NULL || | |
808 | ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE); | |
292a7e47 PR |
809 | |
810 | /* Let's check if we retrieved the embedded ipv6 addresses correctly */ | |
811 | uint32_t i=0; | |
812 | for (i = 0; i < 4; i++) { | |
3cf8b462 JI |
813 | FAIL_IF(p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] || |
814 | p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]); | |
292a7e47 PR |
815 | } |
816 | ||
c5bd04f1 EL |
817 | PACKET_RECYCLE(p); |
818 | FlowShutdown(); | |
1db4aadd | 819 | SCFree(p); |
3cf8b462 | 820 | PASS; |
292a7e47 PR |
821 | } |
822 | ||
823 | /**\test icmpv6 message type: echo request, valid packet | |
824 | * \retval retval 0 = Error ; 1 = ok | |
825 | */ | |
826 | static int ICMPV6EchoReqTest01(void) | |
827 | { | |
292a7e47 PR |
828 | static uint8_t raw_ipv6[] = { |
829 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
830 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
831 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
832 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
833 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
834 | 0x80, 0x00, 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; | |
835 | ||
1db4aadd | 836 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 837 | FAIL_IF_NULL(p); |
292a7e47 PR |
838 | IPV6Hdr ip6h; |
839 | ThreadVars tv; | |
840 | DecodeThreadVars dtv; | |
841 | ||
842 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 843 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
844 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
845 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
846 | ||
847 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 848 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 849 | |
3cf8b462 | 850 | FAIL_IF_NULL(p->icmpv6h); |
292a7e47 | 851 | |
1db4aadd | 852 | SCLogDebug("ID: %u seq: %u", ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); |
292a7e47 | 853 | |
1db4aadd | 854 | if (ICMPV6_GET_TYPE(p) != 128 || ICMPV6_GET_CODE(p) != 0 || |
11be9bd9 | 855 | SCNtohs(ICMPV6_GET_ID(p)) != 9712 || SCNtohs(ICMPV6_GET_SEQ(p)) != 29987) { |
4b4111e9 | 856 | printf("ICMPv6 Echo reply decode failed TYPE %u CODE %u ID %04x(%u) SEQ %04x(%u): ", |
11be9bd9 VJ |
857 | ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), SCNtohs(ICMPV6_GET_ID(p)), |
858 | ICMPV6_GET_SEQ(p), SCNtohs(ICMPV6_GET_SEQ(p))); | |
3cf8b462 | 859 | FAIL; |
292a7e47 PR |
860 | } |
861 | ||
c5bd04f1 EL |
862 | PACKET_RECYCLE(p); |
863 | FlowShutdown(); | |
1db4aadd | 864 | SCFree(p); |
3cf8b462 | 865 | PASS; |
292a7e47 PR |
866 | } |
867 | ||
868 | /**\test icmpv6 message type: echo reply, valid packet | |
869 | * \retval retval 0 = Error ; 1 = ok | |
870 | */ | |
871 | static int ICMPV6EchoRepTest01(void) | |
872 | { | |
292a7e47 PR |
873 | static uint8_t raw_ipv6[] = { |
874 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, | |
875 | 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
876 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
877 | 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, | |
878 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
879 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x00, | |
880 | 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; | |
881 | ||
1db4aadd | 882 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 883 | FAIL_IF_NULL(p); |
292a7e47 PR |
884 | IPV6Hdr ip6h; |
885 | ThreadVars tv; | |
886 | DecodeThreadVars dtv; | |
887 | ||
888 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 889 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
890 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
891 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
892 | ||
893 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 894 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 895 | |
3cf8b462 | 896 | FAIL_IF_NULL(p->icmpv6h); |
292a7e47 | 897 | |
1db4aadd EL |
898 | SCLogDebug("type: %u code %u ID: %u seq: %u", ICMPV6_GET_TYPE(p), |
899 | ICMPV6_GET_CODE(p),ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); | |
292a7e47 | 900 | |
1db4aadd | 901 | if (ICMPV6_GET_TYPE(p) != 129 || ICMPV6_GET_CODE(p) != 0 || |
11be9bd9 | 902 | SCNtohs(ICMPV6_GET_ID(p)) != 9712 || SCNtohs(ICMPV6_GET_SEQ(p)) != 29987) { |
4b4111e9 | 903 | printf("ICMPv6 Echo reply decode failed TYPE %u CODE %u ID %04x(%u) SEQ %04x(%u): ", |
11be9bd9 VJ |
904 | ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), SCNtohs(ICMPV6_GET_ID(p)), |
905 | ICMPV6_GET_SEQ(p), SCNtohs(ICMPV6_GET_SEQ(p))); | |
3cf8b462 | 906 | FAIL; |
292a7e47 PR |
907 | } |
908 | ||
c5bd04f1 EL |
909 | PACKET_RECYCLE(p); |
910 | FlowShutdown(); | |
1db4aadd | 911 | SCFree(p); |
3cf8b462 | 912 | PASS; |
292a7e47 PR |
913 | } |
914 | ||
915 | /** \test icmpv6 message type: parameter problem, invalid packet | |
916 | * \brief set the event ICMPV6_IPV6_UNKNOWN_VER properly when the embedded packet has an unknown version | |
917 | * \retval retval 0 = Error ; 1 = ok | |
918 | */ | |
919 | static int ICMPV6ParamProbTest02(void) | |
920 | { | |
292a7e47 PR |
921 | static uint8_t raw_ipv6[] = { |
922 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, | |
923 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
924 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
925 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
926 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
927 | 0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf, | |
928 | 0x38, 0x70, 0x12, 0xb7, 0x00, 0x08, 0x3a, 0xff, | |
929 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
930 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
931 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
932 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
933 | 0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40 }; | |
934 | ||
1db4aadd | 935 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 936 | FAIL_IF_NULL(p); |
292a7e47 PR |
937 | IPV6Hdr ip6h; |
938 | ThreadVars tv; | |
939 | DecodeThreadVars dtv; | |
940 | ||
941 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 942 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
943 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
944 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
945 | ||
946 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 947 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 948 | |
3cf8b462 JI |
949 | FAIL_IF_NULL(p->icmpv6h); |
950 | FAIL_IF(ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0); | |
951 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER)); | |
292a7e47 | 952 | |
c5bd04f1 EL |
953 | PACKET_RECYCLE(p); |
954 | FlowShutdown(); | |
1db4aadd | 955 | SCFree(p); |
3cf8b462 | 956 | PASS; |
292a7e47 PR |
957 | } |
958 | ||
959 | /** \test icmpv6 message type: packet too big, invalid packet | |
960 | * \brief Set the event ICMPV6_UNKNOWN_CODE if code is invalid for this type | |
961 | * \retval retval 0 = Error ; 1 = ok | |
962 | */ | |
963 | static int ICMPV6PktTooBigTest02(void) | |
964 | { | |
292a7e47 PR |
965 | static uint8_t raw_ipv6[] = { |
966 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, | |
967 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
968 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
969 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
970 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
971 | 0x02, 0x10, 0x5c, 0x7a, 0x00, 0x00, 0x05, 0x00, | |
972 | 0x64, 0x14, 0xfd, 0xff, 0x00, 0x00, 0x3b, 0xff, | |
973 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
974 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
975 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
976 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; | |
977 | ||
1db4aadd | 978 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 979 | FAIL_IF_NULL(p); |
292a7e47 PR |
980 | IPV6Hdr ip6h; |
981 | ThreadVars tv; | |
982 | DecodeThreadVars dtv; | |
983 | ||
984 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 985 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
986 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
987 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
988 | ||
989 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 990 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 991 | |
3cf8b462 JI |
992 | FAIL_IF_NULL(p->icmpv6h); |
993 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); | |
292a7e47 | 994 | |
c5bd04f1 EL |
995 | PACKET_RECYCLE(p); |
996 | FlowShutdown(); | |
1db4aadd | 997 | SCFree(p); |
3cf8b462 | 998 | PASS; |
292a7e47 PR |
999 | } |
1000 | ||
1001 | /** \test icmpv6 message type: time exceed, invalid packet | |
1002 | * \brief set the event ICMPV6_PKT_TOO_SMALL properly | |
1003 | * \retval retval 0 = Error ; 1 = ok | |
1004 | */ | |
1005 | static int ICMPV6TimeExceedTest02(void) | |
1006 | { | |
292a7e47 PR |
1007 | static uint8_t raw_ipv6[] = { |
1008 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3a, 0xff, | |
1009 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1010 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1011 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1012 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
1013 | 0x02, 0x10, 0x5c }; | |
1014 | ||
1015 | /* The icmpv6 header is broken in the checksum (so we dont have a complete header) */ | |
1016 | ||
1db4aadd | 1017 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 1018 | FAIL_IF_NULL(p); |
292a7e47 PR |
1019 | IPV6Hdr ip6h; |
1020 | ThreadVars tv; | |
1021 | DecodeThreadVars dtv; | |
1022 | ||
1023 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 1024 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
1025 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
1026 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1027 | ||
1028 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1029 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 1030 | |
3cf8b462 | 1031 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_PKT_TOO_SMALL)); |
292a7e47 | 1032 | |
c5bd04f1 EL |
1033 | PACKET_RECYCLE(p); |
1034 | FlowShutdown(); | |
1db4aadd | 1035 | SCFree(p); |
3cf8b462 | 1036 | PASS; |
292a7e47 PR |
1037 | } |
1038 | ||
1039 | /**\test icmpv6 message type: destination unreach, invalid packet | |
1040 | * \brief The embedded packet header (ipv6) is truncated | |
1041 | * \retval retval 0 = Error ; 1 = ok | |
1042 | */ | |
1043 | static int ICMPV6DestUnreachTest02(void) | |
1044 | { | |
292a7e47 PR |
1045 | static uint8_t raw_ipv6[] = { |
1046 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0xff, | |
1047 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1048 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1049 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1050 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
1051 | 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, | |
1052 | 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, | |
1053 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1054 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1055 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1056 | 0x00, 0x00, 0x00, 0x00, 0x00 }; | |
1057 | ||
1db4aadd | 1058 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 1059 | FAIL_IF_NULL(p); |
292a7e47 PR |
1060 | IPV6Hdr ip6h; |
1061 | ThreadVars tv; | |
1062 | DecodeThreadVars dtv; | |
1063 | ||
1064 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 1065 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
1066 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
1067 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1068 | ||
1069 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1070 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 1071 | |
3cf8b462 | 1072 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_IPV6_TRUNC_PKT)); |
292a7e47 | 1073 | |
c5bd04f1 EL |
1074 | PACKET_RECYCLE(p); |
1075 | FlowShutdown(); | |
1db4aadd | 1076 | SCFree(p); |
3cf8b462 | 1077 | PASS; |
292a7e47 PR |
1078 | } |
1079 | ||
1080 | /**\test icmpv6 message type: echo request, invalid packet | |
1081 | * \brief unknown code | |
1082 | * \retval retval 0 = Error ; 1 = ok | |
1083 | */ | |
1084 | static int ICMPV6EchoReqTest02(void) | |
1085 | { | |
292a7e47 PR |
1086 | static uint8_t raw_ipv6[] = { |
1087 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, | |
1088 | 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1089 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1090 | 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, | |
1091 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1092 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, | |
1093 | 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; | |
1094 | ||
1db4aadd | 1095 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 1096 | FAIL_IF_NULL(p); |
292a7e47 PR |
1097 | IPV6Hdr ip6h; |
1098 | ThreadVars tv; | |
1099 | DecodeThreadVars dtv; | |
1100 | ||
1101 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 1102 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
1103 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
1104 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1105 | ||
1106 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1107 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 1108 | |
3cf8b462 | 1109 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
292a7e47 | 1110 | |
c5bd04f1 EL |
1111 | PACKET_RECYCLE(p); |
1112 | FlowShutdown(); | |
1db4aadd | 1113 | SCFree(p); |
3cf8b462 | 1114 | PASS; |
292a7e47 PR |
1115 | } |
1116 | ||
1117 | /**\test icmpv6 message type: echo reply, invalid packet | |
1118 | * \brief unknown code | |
1119 | * \retval retval 0 = Error ; 1 = ok | |
1120 | */ | |
1121 | static int ICMPV6EchoRepTest02(void) | |
1122 | { | |
292a7e47 PR |
1123 | static uint8_t raw_ipv6[] = { |
1124 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, | |
1125 | 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1126 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1127 | 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, | |
1128 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1129 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x01, | |
1130 | 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; | |
1131 | ||
1db4aadd | 1132 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 1133 | FAIL_IF_NULL(p); |
292a7e47 PR |
1134 | IPV6Hdr ip6h; |
1135 | ThreadVars tv; | |
1136 | DecodeThreadVars dtv; | |
1137 | ||
1138 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 1139 | memset(p, 0, SIZE_OF_PACKET); |
292a7e47 PR |
1140 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
1141 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1142 | ||
1143 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1144 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
292a7e47 | 1145 | |
3cf8b462 | 1146 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
292a7e47 | 1147 | |
c5bd04f1 EL |
1148 | PACKET_RECYCLE(p); |
1149 | FlowShutdown(); | |
1db4aadd | 1150 | SCFree(p); |
3cf8b462 | 1151 | PASS; |
292a7e47 PR |
1152 | } |
1153 | ||
9a2bcb6a GS |
1154 | /**\test icmpv6 packet decoding and setting up of payload_len and payload buufer |
1155 | * \retval retval 0 = Error ; 1 = ok | |
1156 | */ | |
1157 | static int ICMPV6PayloadTest01(void) | |
1158 | { | |
9a2bcb6a GS |
1159 | static uint8_t raw_ipv6[] = { |
1160 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0xff, | |
1161 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1162 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1163 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
1165 | 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, | |
1166 | 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, | |
1167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1169 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1170 | 0x00, 0x00, 0x00, 0x00, 0x00 }; | |
1171 | ||
1db4aadd | 1172 | Packet *p = SCMalloc(SIZE_OF_PACKET); |
3cf8b462 | 1173 | FAIL_IF_NULL(p); |
9a2bcb6a GS |
1174 | IPV6Hdr ip6h; |
1175 | ThreadVars tv; | |
1176 | DecodeThreadVars dtv; | |
1177 | ||
1178 | memset(&tv, 0, sizeof(ThreadVars)); | |
1db4aadd | 1179 | memset(p, 0, SIZE_OF_PACKET); |
9a2bcb6a GS |
1180 | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
1181 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1182 | ||
1183 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1184 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
9a2bcb6a | 1185 | |
3cf8b462 JI |
1186 | FAIL_IF_NULL(p->payload); |
1187 | FAIL_IF(p->payload_len != 37); | |
8dceb278 | 1188 | |
c5bd04f1 EL |
1189 | PACKET_RECYCLE(p); |
1190 | FlowShutdown(); | |
1db4aadd | 1191 | SCFree(p); |
3cf8b462 | 1192 | PASS; |
9a2bcb6a GS |
1193 | } |
1194 | ||
7a9da787 JI |
1195 | static int ICMPV6RouterSolicitTestKnownCode(void) |
1196 | { | |
7a9da787 JI |
1197 | static uint8_t raw_ipv6[] = { |
1198 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1199 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1200 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1201 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1202 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1203 | 0x85, 0x00, 0xbe, 0xb0, 0x00, 0x00, 0x00, 0x00 | |
1204 | }; | |
1205 | ||
1206 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1207 | FAIL_IF_NULL(p); |
7a9da787 JI |
1208 | IPV6Hdr ip6h; |
1209 | ThreadVars tv; | |
1210 | DecodeThreadVars dtv; | |
1211 | ||
1212 | memset(&tv, 0, sizeof(ThreadVars)); | |
1213 | memset(p, 0, SIZE_OF_PACKET); | |
1214 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1215 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1216 | ||
1217 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1218 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1219 | |
3cf8b462 | 1220 | FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1221 | |
7a9da787 JI |
1222 | PACKET_RECYCLE(p); |
1223 | FlowShutdown(); | |
1224 | SCFree(p); | |
3cf8b462 | 1225 | PASS; |
7a9da787 JI |
1226 | } |
1227 | ||
1228 | static int ICMPV6RouterSolicitTestUnknownCode(void) | |
1229 | { | |
7a9da787 JI |
1230 | static uint8_t raw_ipv6[] = { |
1231 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1232 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1233 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1234 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1236 | 0x85, 0x01, 0xbe, 0xaf, 0x00, 0x00, 0x00, 0x00 | |
1237 | }; | |
1238 | ||
1239 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1240 | FAIL_IF_NULL(p); |
7a9da787 JI |
1241 | IPV6Hdr ip6h; |
1242 | ThreadVars tv; | |
1243 | DecodeThreadVars dtv; | |
1244 | ||
1245 | memset(&tv, 0, sizeof(ThreadVars)); | |
1246 | memset(p, 0, SIZE_OF_PACKET); | |
1247 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1248 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1249 | ||
1250 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1251 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1252 | |
3cf8b462 | 1253 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1254 | |
7a9da787 JI |
1255 | PACKET_RECYCLE(p); |
1256 | FlowShutdown(); | |
1257 | SCFree(p); | |
3cf8b462 | 1258 | PASS; |
7a9da787 JI |
1259 | } |
1260 | ||
1261 | static int ICMPV6RouterAdvertTestKnownCode(void) | |
1262 | { | |
7a9da787 JI |
1263 | static uint8_t raw_ipv6[] = { |
1264 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1265 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1266 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1267 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1268 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1269 | 0x86, 0x00, 0xbd, 0xb0, 0x00, 0x00, 0x00, 0x00 | |
1270 | }; | |
1271 | ||
1272 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1273 | FAIL_IF_NULL(p); |
7a9da787 JI |
1274 | IPV6Hdr ip6h; |
1275 | ThreadVars tv; | |
1276 | DecodeThreadVars dtv; | |
1277 | ||
1278 | memset(&tv, 0, sizeof(ThreadVars)); | |
1279 | memset(p, 0, SIZE_OF_PACKET); | |
1280 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1281 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1282 | ||
1283 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1284 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1285 | |
3cf8b462 | 1286 | FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1287 | |
7a9da787 JI |
1288 | PACKET_RECYCLE(p); |
1289 | FlowShutdown(); | |
1290 | SCFree(p); | |
3cf8b462 | 1291 | PASS; |
7a9da787 JI |
1292 | } |
1293 | ||
1294 | static int ICMPV6RouterAdvertTestUnknownCode(void) | |
1295 | { | |
7a9da787 JI |
1296 | static uint8_t raw_ipv6[] = { |
1297 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1298 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1299 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1300 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1301 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1302 | 0x86, 0x01, 0xbd, 0xaf, 0x00, 0x00, 0x00, 0x00 | |
1303 | }; | |
1304 | ||
1305 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1306 | FAIL_IF_NULL(p); |
7a9da787 JI |
1307 | IPV6Hdr ip6h; |
1308 | ThreadVars tv; | |
1309 | DecodeThreadVars dtv; | |
1310 | ||
1311 | memset(&tv, 0, sizeof(ThreadVars)); | |
1312 | memset(p, 0, SIZE_OF_PACKET); | |
1313 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1314 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1315 | ||
1316 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1317 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1318 | |
3cf8b462 | 1319 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1320 | |
7a9da787 JI |
1321 | PACKET_RECYCLE(p); |
1322 | FlowShutdown(); | |
1323 | SCFree(p); | |
3cf8b462 | 1324 | PASS; |
7a9da787 JI |
1325 | } |
1326 | ||
1327 | static int ICMPV6NeighbourSolicitTestKnownCode(void) | |
1328 | { | |
7a9da787 JI |
1329 | static uint8_t raw_ipv6[] = { |
1330 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1331 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1332 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1333 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1334 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1335 | 0x87, 0x00, 0xbc, 0xb0, 0x00, 0x00, 0x00, 0x00 | |
1336 | }; | |
1337 | ||
1338 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1339 | FAIL_IF_NULL(p); |
7a9da787 JI |
1340 | IPV6Hdr ip6h; |
1341 | ThreadVars tv; | |
1342 | DecodeThreadVars dtv; | |
1343 | ||
1344 | memset(&tv, 0, sizeof(ThreadVars)); | |
1345 | memset(p, 0, SIZE_OF_PACKET); | |
1346 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1347 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1348 | ||
1349 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1350 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1351 | |
3cf8b462 | 1352 | FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1353 | |
7a9da787 JI |
1354 | PACKET_RECYCLE(p); |
1355 | FlowShutdown(); | |
1356 | SCFree(p); | |
3cf8b462 | 1357 | PASS; |
7a9da787 JI |
1358 | } |
1359 | ||
1360 | static int ICMPV6NeighbourSolicitTestUnknownCode(void) | |
1361 | { | |
7a9da787 JI |
1362 | static uint8_t raw_ipv6[] = { |
1363 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1364 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1365 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1366 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1367 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1368 | 0x87, 0x01, 0xbc, 0xaf, 0x00, 0x00, 0x00, 0x00 | |
1369 | }; | |
1370 | ||
1371 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1372 | FAIL_IF_NULL(p); |
7a9da787 JI |
1373 | IPV6Hdr ip6h; |
1374 | ThreadVars tv; | |
1375 | DecodeThreadVars dtv; | |
1376 | ||
1377 | memset(&tv, 0, sizeof(ThreadVars)); | |
1378 | memset(p, 0, SIZE_OF_PACKET); | |
1379 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1380 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1381 | ||
1382 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1383 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1384 | |
3cf8b462 | 1385 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1386 | |
7a9da787 JI |
1387 | PACKET_RECYCLE(p); |
1388 | FlowShutdown(); | |
1389 | SCFree(p); | |
3cf8b462 | 1390 | PASS; |
7a9da787 JI |
1391 | } |
1392 | ||
1393 | static int ICMPV6NeighbourAdvertTestKnownCode(void) | |
1394 | { | |
7a9da787 JI |
1395 | static uint8_t raw_ipv6[] = { |
1396 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1397 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1398 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1399 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1400 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1401 | 0x88, 0x00, 0xbb, 0xb0, 0x00, 0x00, 0x00, 0x00 | |
1402 | }; | |
1403 | ||
1404 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1405 | FAIL_IF_NULL(p); |
7a9da787 JI |
1406 | IPV6Hdr ip6h; |
1407 | ThreadVars tv; | |
1408 | DecodeThreadVars dtv; | |
1409 | ||
1410 | memset(&tv, 0, sizeof(ThreadVars)); | |
1411 | memset(p, 0, SIZE_OF_PACKET); | |
1412 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1413 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1414 | ||
1415 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1416 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1417 | |
3cf8b462 | 1418 | FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1419 | |
7a9da787 JI |
1420 | PACKET_RECYCLE(p); |
1421 | FlowShutdown(); | |
1422 | SCFree(p); | |
3cf8b462 | 1423 | PASS; |
7a9da787 JI |
1424 | } |
1425 | ||
1426 | static int ICMPV6NeighbourAdvertTestUnknownCode(void) | |
1427 | { | |
7a9da787 JI |
1428 | static uint8_t raw_ipv6[] = { |
1429 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1430 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1431 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1432 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1433 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1434 | 0x88, 0x01, 0xbb, 0xaf, 0x00, 0x00, 0x00, 0x00 | |
1435 | }; | |
1436 | ||
1437 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1438 | FAIL_IF_NULL(p); |
7a9da787 JI |
1439 | IPV6Hdr ip6h; |
1440 | ThreadVars tv; | |
1441 | DecodeThreadVars dtv; | |
1442 | ||
1443 | memset(&tv, 0, sizeof(ThreadVars)); | |
1444 | memset(p, 0, SIZE_OF_PACKET); | |
1445 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1446 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1447 | ||
1448 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1449 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1450 | |
3cf8b462 | 1451 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1452 | |
7a9da787 JI |
1453 | PACKET_RECYCLE(p); |
1454 | FlowShutdown(); | |
1455 | SCFree(p); | |
3cf8b462 | 1456 | PASS; |
7a9da787 JI |
1457 | } |
1458 | ||
1459 | static int ICMPV6RedirectTestKnownCode(void) | |
1460 | { | |
7a9da787 JI |
1461 | static uint8_t raw_ipv6[] = { |
1462 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1463 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1464 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1465 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1466 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1467 | 0x89, 0x00, 0xba, 0xb0, 0x00, 0x00, 0x00, 0x00 | |
1468 | }; | |
1469 | ||
1470 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1471 | FAIL_IF_NULL(p); |
7a9da787 JI |
1472 | IPV6Hdr ip6h; |
1473 | ThreadVars tv; | |
1474 | DecodeThreadVars dtv; | |
1475 | ||
1476 | memset(&tv, 0, sizeof(ThreadVars)); | |
1477 | memset(p, 0, SIZE_OF_PACKET); | |
1478 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1479 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1480 | ||
1481 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1482 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1483 | |
3cf8b462 | 1484 | FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1485 | |
7a9da787 JI |
1486 | PACKET_RECYCLE(p); |
1487 | FlowShutdown(); | |
1488 | SCFree(p); | |
3cf8b462 | 1489 | PASS; |
7a9da787 JI |
1490 | } |
1491 | ||
1492 | static int ICMPV6RedirectTestUnknownCode(void) | |
1493 | { | |
7a9da787 JI |
1494 | static uint8_t raw_ipv6[] = { |
1495 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, | |
1496 | 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1497 | 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, | |
1498 | 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1499 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | |
1500 | 0x89, 0x01, 0xba, 0xaf, 0x00, 0x00, 0x00, 0x00 | |
1501 | }; | |
1502 | ||
1503 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
3cf8b462 | 1504 | FAIL_IF_NULL(p); |
7a9da787 JI |
1505 | IPV6Hdr ip6h; |
1506 | ThreadVars tv; | |
1507 | DecodeThreadVars dtv; | |
1508 | ||
1509 | memset(&tv, 0, sizeof(ThreadVars)); | |
1510 | memset(p, 0, SIZE_OF_PACKET); | |
1511 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1512 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1513 | ||
1514 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1515 | DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); |
7a9da787 | 1516 | |
3cf8b462 | 1517 | FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)); |
7a9da787 | 1518 | |
7a9da787 JI |
1519 | PACKET_RECYCLE(p); |
1520 | FlowShutdown(); | |
1521 | SCFree(p); | |
3cf8b462 | 1522 | PASS; |
7a9da787 JI |
1523 | } |
1524 | ||
af4085b7 JI |
1525 | /** |
1526 | * \test Test for valid ICMPv6 checksum when the FCS is still attached. | |
1527 | * | |
1528 | * Tests that the packet is decoded with sufficient info to verify the | |
1529 | * checksum even if the packet has some trailing data like an ethernet | |
1530 | * FCS. | |
1531 | */ | |
1532 | static int ICMPV6CalculateValidChecksumWithFCS(void) | |
1533 | { | |
1534 | /* IPV6/ICMPv6 packet with ethernet header. | |
1535 | * - IPv6 payload length: 36 | |
1536 | */ | |
1537 | uint8_t raw_ipv6[] = { | |
1538 | 0x33, 0x33, 0x00, 0x00, 0x00, 0x16, 0x00, 0x50, | |
1539 | 0x56, 0xa6, 0x6a, 0x7d, 0x86, 0xdd, 0x60, 0x00, | |
1540 | 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0xfe, 0x80, | |
1541 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x09, | |
1542 | 0xad, 0x44, 0x49, 0x38, 0x5f, 0xa9, 0xff, 0x02, | |
1543 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1544 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x3a, 0x00, | |
1545 | 0x05, 0x02, 0x00, 0x00, 0x01, 0x00, 0x8f, 0x00, | |
1546 | 0x24, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, /* Checksum: 0x24e0. */ | |
1547 | 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, | |
1548 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1549 | 0x00, 0xfb, 0x1f, 0x34, 0xf6, 0xa4 | |
1550 | }; | |
1551 | uint16_t csum = *(((uint16_t *)(raw_ipv6 + 64))); | |
1552 | ||
1553 | Packet *p = SCMalloc(SIZE_OF_PACKET); | |
1554 | FAIL_IF_NULL(p); | |
1555 | IPV6Hdr ip6h; | |
1556 | ThreadVars tv; | |
1557 | DecodeThreadVars dtv; | |
1558 | ||
1559 | memset(&tv, 0, sizeof(ThreadVars)); | |
1560 | memset(p, 0, SIZE_OF_PACKET); | |
1561 | memset(&dtv, 0, sizeof(DecodeThreadVars)); | |
1562 | memset(&ip6h, 0, sizeof(IPV6Hdr)); | |
1563 | ||
1564 | FlowInitConfig(FLOW_QUIET); | |
f8aed4ce | 1565 | DecodeIPV6(&tv, &dtv, p, raw_ipv6 + 14, sizeof(raw_ipv6) - 14); |
af4085b7 JI |
1566 | FAIL_IF_NULL(p->icmpv6h); |
1567 | ||
1568 | uint16_t icmpv6_len = IPV6_GET_RAW_PLEN(p->ip6h) - | |
1569 | ((uint8_t *)p->icmpv6h - (uint8_t *)p->ip6h - IPV6_HEADER_LEN); | |
1570 | FAIL_IF(icmpv6_len != 28); | |
1571 | FAIL_IF(ICMPV6CalculateChecksum(p->ip6h->s_ip6_addrs, | |
1572 | (uint16_t *)p->icmpv6h, icmpv6_len) != csum); | |
1573 | ||
1574 | PACKET_RECYCLE(p); | |
1575 | FlowShutdown(); | |
1576 | SCFree(p); | |
1577 | PASS; | |
1578 | } | |
1579 | ||
292a7e47 | 1580 | #endif /* UNITTESTS */ |
401a0313 AS |
1581 | /** |
1582 | * \brief Registers ICMPV6 unit tests | |
1583 | * \todo More ICMPv6 tests | |
1584 | */ | |
1585 | void DecodeICMPV6RegisterTests(void) | |
1586 | { | |
c43319c3 | 1587 | #ifdef UNITTESTS |
796dd522 JI |
1588 | UtRegisterTest("ICMPV6CalculateValidChecksumtest01", |
1589 | ICMPV6CalculateValidChecksumtest01); | |
1590 | UtRegisterTest("ICMPV6CalculateInValidChecksumtest02", | |
1591 | ICMPV6CalculateInvalidChecksumtest02); | |
1592 | ||
1593 | UtRegisterTest("ICMPV6ParamProbTest01 (Valid)", ICMPV6ParamProbTest01); | |
1594 | UtRegisterTest("ICMPV6DestUnreachTest01 (Valid)", ICMPV6DestUnreachTest01); | |
1595 | UtRegisterTest("ICMPV6PktTooBigTest01 (Valid)", ICMPV6PktTooBigTest01); | |
1596 | UtRegisterTest("ICMPV6TimeExceedTest01 (Valid)", ICMPV6TimeExceedTest01); | |
1597 | UtRegisterTest("ICMPV6EchoReqTest01 (Valid)", ICMPV6EchoReqTest01); | |
1598 | UtRegisterTest("ICMPV6EchoRepTest01 (Valid)", ICMPV6EchoRepTest01); | |
1599 | ||
1600 | UtRegisterTest("ICMPV6ParamProbTest02 (Invalid)", ICMPV6ParamProbTest02); | |
1601 | UtRegisterTest("ICMPV6DestUnreachTest02 (Invalid)", | |
1602 | ICMPV6DestUnreachTest02); | |
1603 | UtRegisterTest("ICMPV6PktTooBigTest02 (Invalid)", ICMPV6PktTooBigTest02); | |
1604 | UtRegisterTest("ICMPV6TimeExceedTest02 (Invalid)", ICMPV6TimeExceedTest02); | |
1605 | UtRegisterTest("ICMPV6EchoReqTest02 (Invalid)", ICMPV6EchoReqTest02); | |
1606 | UtRegisterTest("ICMPV6EchoRepTest02 (Invalid)", ICMPV6EchoRepTest02); | |
1607 | ||
1608 | UtRegisterTest("ICMPV6PayloadTest01", ICMPV6PayloadTest01); | |
7a9da787 JI |
1609 | |
1610 | UtRegisterTest("ICMPV6RouterSolicitTestKnownCode", | |
796dd522 | 1611 | ICMPV6RouterSolicitTestKnownCode); |
7a9da787 | 1612 | UtRegisterTest("ICMPV6RouterSolicitTestUnknownCode", |
796dd522 | 1613 | ICMPV6RouterSolicitTestUnknownCode); |
7a9da787 | 1614 | UtRegisterTest("ICMPV6RouterAdvertTestKnownCode", |
796dd522 | 1615 | ICMPV6RouterAdvertTestKnownCode); |
7a9da787 | 1616 | UtRegisterTest("ICMPV6RouterAdvertTestUnknownCode", |
796dd522 | 1617 | ICMPV6RouterAdvertTestUnknownCode); |
7a9da787 JI |
1618 | |
1619 | UtRegisterTest("ICMPV6NeighbourSolicitTestKnownCode", | |
796dd522 | 1620 | ICMPV6NeighbourSolicitTestKnownCode); |
7a9da787 | 1621 | UtRegisterTest("ICMPV6NeighbourSolicitTestUnknownCode", |
796dd522 | 1622 | ICMPV6NeighbourSolicitTestUnknownCode); |
7a9da787 | 1623 | UtRegisterTest("ICMPV6NeighbourAdvertTestKnownCode", |
796dd522 | 1624 | ICMPV6NeighbourAdvertTestKnownCode); |
7a9da787 | 1625 | UtRegisterTest("ICMPV6NeighbourAdvertTestUnknownCode", |
796dd522 | 1626 | ICMPV6NeighbourAdvertTestUnknownCode); |
7a9da787 | 1627 | |
796dd522 | 1628 | UtRegisterTest("ICMPV6RedirectTestKnownCode", ICMPV6RedirectTestKnownCode); |
7a9da787 | 1629 | UtRegisterTest("ICMPV6RedirectTestUnknownCode", |
796dd522 | 1630 | ICMPV6RedirectTestUnknownCode); |
af4085b7 JI |
1631 | UtRegisterTest("ICMPV6CalculateValidChecksumWithFCS", |
1632 | ICMPV6CalculateValidChecksumWithFCS); | |
c43319c3 | 1633 | #endif /* UNITTESTS */ |
401a0313 | 1634 | } |
acf10525 EL |
1635 | /** |
1636 | * @} | |
1637 | */ |