decode/icmpv6: move icmpv6h into L4 packet data

Also start vars section in L4 for icmpv6vars.

To reduce Packet size.

Ticket: #6938.
pull/10971/head
Victor Julien 1 year ago committed by Victor Julien
parent 30ae13f2c3
commit b959d1dba8

@ -37,6 +37,14 @@
#include "util-print.h" #include "util-print.h"
#include "util-validate.h" #include "util-validate.h"
#if defined(DEBUG) || defined(UNITTESTS)
static inline const IPV6Hdr *PacketGetICMPv6EmbIPv6(const Packet *p)
{
BUG_ON(p->l4.type != PACKET_L4_ICMPV6);
return p->l4.vars.icmpv6.emb_ipv6h;
}
#endif
/** /**
* \brief Get variables and do some checks of the embedded IPV6 packet * \brief Get variables and do some checks of the embedded IPV6 packet
* *
@ -66,51 +74,51 @@ static void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len )
return; return;
} }
/** We need to fill icmpv6vars */ /** We need to fill l4.vars.icmpv6 */
p->icmpv6vars.emb_ipv6h = icmp6_ip6h; p->l4.vars.icmpv6.emb_ipv6h = icmp6_ip6h;
/** Get protocol and ports inside the embedded ipv6 packet and set the pointers */ /** Get protocol and ports inside the embedded ipv6 packet and set the pointers */
p->icmpv6vars.emb_ip6_proto_next = icmp6_ip6h->s_ip6_nxt; p->l4.vars.icmpv6.emb_ip6_proto_next = icmp6_ip6h->s_ip6_nxt;
switch (icmp6_ip6h->s_ip6_nxt) { switch (icmp6_ip6h->s_ip6_nxt) {
case IPPROTO_TCP: case IPPROTO_TCP:
if (len >= IPV6_HEADER_LEN + TCP_HEADER_LEN ) { if (len >= IPV6_HEADER_LEN + TCP_HEADER_LEN ) {
TCPHdr *emb_tcph = (TCPHdr *)(partial_packet + IPV6_HEADER_LEN); TCPHdr *emb_tcph = (TCPHdr *)(partial_packet + IPV6_HEADER_LEN);
p->icmpv6vars.emb_sport = emb_tcph->th_sport; p->l4.vars.icmpv6.emb_sport = emb_tcph->th_sport;
p->icmpv6vars.emb_dport = emb_tcph->th_dport; p->l4.vars.icmpv6.emb_dport = emb_tcph->th_dport;
p->icmpv6vars.emb_ports_set = true; p->l4.vars.icmpv6.emb_ports_set = true;
SCLogDebug("ICMPV6->IPV6->TCP header sport: " SCLogDebug("ICMPV6->IPV6->TCP header sport: "
"%"PRIu16" dport %"PRIu16"", p->icmpv6vars.emb_sport, "%" PRIu16 " dport %" PRIu16 "",
p->icmpv6vars.emb_dport); p->l4.vars.icmpv6.emb_sport, p->l4.vars.icmpv6.emb_dport);
} else { } else {
SCLogDebug("Warning, ICMPV6->IPV6->TCP " SCLogDebug("Warning, ICMPV6->IPV6->TCP "
"header Didn't fit in the packet!"); "header Didn't fit in the packet!");
p->icmpv6vars.emb_sport = 0; p->l4.vars.icmpv6.emb_sport = 0;
p->icmpv6vars.emb_dport = 0; p->l4.vars.icmpv6.emb_dport = 0;
} }
break; break;
case IPPROTO_UDP: case IPPROTO_UDP:
if (len >= IPV6_HEADER_LEN + UDP_HEADER_LEN ) { if (len >= IPV6_HEADER_LEN + UDP_HEADER_LEN ) {
UDPHdr *emb_udph = (UDPHdr *)(partial_packet + IPV6_HEADER_LEN); UDPHdr *emb_udph = (UDPHdr *)(partial_packet + IPV6_HEADER_LEN);
p->icmpv6vars.emb_sport = emb_udph->uh_sport; p->l4.vars.icmpv6.emb_sport = emb_udph->uh_sport;
p->icmpv6vars.emb_dport = emb_udph->uh_dport; p->l4.vars.icmpv6.emb_dport = emb_udph->uh_dport;
p->icmpv6vars.emb_ports_set = true; p->l4.vars.icmpv6.emb_ports_set = true;
SCLogDebug("ICMPV6->IPV6->UDP header sport: " SCLogDebug("ICMPV6->IPV6->UDP header sport: "
"%"PRIu16" dport %"PRIu16"", p->icmpv6vars.emb_sport, "%" PRIu16 " dport %" PRIu16 "",
p->icmpv6vars.emb_dport); p->l4.vars.icmpv6.emb_sport, p->l4.vars.icmpv6.emb_dport);
} else { } else {
SCLogDebug("Warning, ICMPV6->IPV6->UDP " SCLogDebug("Warning, ICMPV6->IPV6->UDP "
"header Didn't fit in the packet!"); "header Didn't fit in the packet!");
p->icmpv6vars.emb_sport = 0; p->l4.vars.icmpv6.emb_sport = 0;
p->icmpv6vars.emb_dport = 0; p->l4.vars.icmpv6.emb_dport = 0;
} }
break; break;
case IPPROTO_ICMPV6: case IPPROTO_ICMPV6:
p->icmpv6vars.emb_sport = 0; p->l4.vars.icmpv6.emb_sport = 0;
p->icmpv6vars.emb_dport = 0; p->l4.vars.icmpv6.emb_dport = 0;
SCLogDebug("ICMPV6->IPV6->ICMP header"); SCLogDebug("ICMPV6->IPV6->ICMP header");
@ -120,8 +128,8 @@ static void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len )
/* debug print */ /* debug print */
#ifdef DEBUG #ifdef DEBUG
char s[46], d[46]; char s[46], d[46];
PrintInet(AF_INET6, (const void *)ICMPV6_GET_EMB_IPV6(p)->s_ip6_src, s, sizeof(s)); PrintInet(AF_INET6, (const void *)PacketGetICMPv6EmbIPv6(p)->s_ip6_src, s, sizeof(s));
PrintInet(AF_INET6, (const void *)ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst, d, sizeof(d)); PrintInet(AF_INET6, (const void *)PacketGetICMPv6EmbIPv6(p)->s_ip6_dst, d, sizeof(d));
SCLogDebug("ICMPv6 embedding IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: " SCLogDebug("ICMPv6 embedding IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: "
"%" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32, "%" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32,
s, d, IPV6_GET_RAW_CLASS(icmp6_ip6h), IPV6_GET_RAW_FLOW(icmp6_ip6h), s, d, IPV6_GET_RAW_CLASS(icmp6_ip6h), IPV6_GET_RAW_FLOW(icmp6_ip6h),
@ -177,10 +185,10 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} }
p->icmpv6h = (ICMPV6Hdr *)pkt; ICMPV6Hdr *icmpv6h = PacketSetICMPv6(p, pkt);
p->proto = IPPROTO_ICMPV6; p->proto = IPPROTO_ICMPV6;
p->icmp_s.type = p->icmpv6h->type; const uint8_t type = p->icmp_s.type = icmpv6h->type;
p->icmp_s.code = p->icmpv6h->code; const uint8_t code = p->icmp_s.code = icmpv6h->code;
DEBUG_VALIDATE_BUG_ON(len - ICMPV6_HEADER_LEN > UINT16_MAX); DEBUG_VALIDATE_BUG_ON(len - ICMPV6_HEADER_LEN > UINT16_MAX);
p->payload_len = (uint16_t)(len - ICMPV6_HEADER_LEN); p->payload_len = (uint16_t)(len - ICMPV6_HEADER_LEN);
p->payload = (uint8_t *)pkt + ICMPV6_HEADER_LEN; p->payload = (uint8_t *)pkt + ICMPV6_HEADER_LEN;
@ -190,14 +198,13 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
p->icmp_d.type = (uint8_t)ctype; p->icmp_d.type = (uint8_t)ctype;
} }
SCLogDebug("ICMPV6 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv6h->type, SCLogDebug("ICMPV6 TYPE %u CODE %u", type, code);
p->icmpv6h->code);
switch (ICMPV6_GET_TYPE(p)) { switch (type) {
case ICMP6_DST_UNREACH: case ICMP6_DST_UNREACH:
SCLogDebug("ICMP6_DST_UNREACH"); SCLogDebug("ICMP6_DST_UNREACH");
if (ICMPV6_GET_CODE(p) > ICMP6_DST_UNREACH_REJECTROUTE) { if (code > ICMP6_DST_UNREACH_REJECTROUTE) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else { } else {
if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) { if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
@ -212,13 +219,13 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
case ICMP6_PACKET_TOO_BIG: case ICMP6_PACKET_TOO_BIG:
SCLogDebug("ICMP6_PACKET_TOO_BIG"); SCLogDebug("ICMP6_PACKET_TOO_BIG");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else { } else {
if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) { if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} }
p->icmpv6vars.mtu = ICMPV6_GET_MTU(p); p->l4.vars.icmpv6.mtu = ICMPV6_GET_MTU(icmpv6h);
DecodePartialIPV6(p, (uint8_t *)(pkt + ICMPV6_HEADER_LEN), DecodePartialIPV6(p, (uint8_t *)(pkt + ICMPV6_HEADER_LEN),
(uint16_t)(len - ICMPV6_HEADER_LEN)); (uint16_t)(len - ICMPV6_HEADER_LEN));
full_hdr = 1; full_hdr = 1;
@ -228,7 +235,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
case ICMP6_TIME_EXCEEDED: case ICMP6_TIME_EXCEEDED:
SCLogDebug("ICMP6_TIME_EXCEEDED"); SCLogDebug("ICMP6_TIME_EXCEEDED");
if (ICMPV6_GET_CODE(p) > ICMP6_TIME_EXCEED_REASSEMBLY) { if (code > ICMP6_TIME_EXCEED_REASSEMBLY) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else { } else {
if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) { if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
@ -243,7 +250,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
case ICMP6_PARAM_PROB: case ICMP6_PARAM_PROB:
SCLogDebug("ICMP6_PARAM_PROB"); SCLogDebug("ICMP6_PARAM_PROB");
if (ICMPV6_GET_CODE(p) > ICMP6_PARAMPROB_OPTION) { if (code > ICMP6_PARAMPROB_OPTION) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else { } else {
if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) { if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
@ -256,64 +263,64 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break; break;
case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REQUEST:
SCLogDebug("ICMP6_ECHO_REQUEST id: %u seq: %u", SCLogDebug("ICMP6_ECHO_REQUEST id: %u seq: %u", icmpv6h->icmpv6b.icmpv6i.id,
p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq); icmpv6h->icmpv6b.icmpv6i.seq);
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else { } else {
p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id; p->l4.vars.icmpv6.id = icmpv6h->icmpv6b.icmpv6i.id;
p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq; p->l4.vars.icmpv6.seq = icmpv6h->icmpv6b.icmpv6i.seq;
full_hdr = 1; full_hdr = 1;
} }
break; break;
case ICMP6_ECHO_REPLY: case ICMP6_ECHO_REPLY:
SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u", SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u", icmpv6h->icmpv6b.icmpv6i.id,
p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq); icmpv6h->icmpv6b.icmpv6i.seq);
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else { } else {
p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id; p->l4.vars.icmpv6.id = icmpv6h->icmpv6b.icmpv6i.id;
p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq; p->l4.vars.icmpv6.seq = icmpv6h->icmpv6b.icmpv6i.seq;
full_hdr = 1; full_hdr = 1;
} }
break; break;
case ND_ROUTER_SOLICIT: case ND_ROUTER_SOLICIT:
SCLogDebug("ND_ROUTER_SOLICIT"); SCLogDebug("ND_ROUTER_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case ND_ROUTER_ADVERT: case ND_ROUTER_ADVERT:
SCLogDebug("ND_ROUTER_ADVERT"); SCLogDebug("ND_ROUTER_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case ND_NEIGHBOR_SOLICIT: case ND_NEIGHBOR_SOLICIT:
SCLogDebug("ND_NEIGHBOR_SOLICIT"); SCLogDebug("ND_NEIGHBOR_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case ND_NEIGHBOR_ADVERT: case ND_NEIGHBOR_ADVERT:
SCLogDebug("ND_NEIGHBOR_ADVERT"); SCLogDebug("ND_NEIGHBOR_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case ND_REDIRECT: case ND_REDIRECT:
SCLogDebug("ND_REDIRECT"); SCLogDebug("ND_REDIRECT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case MLD_LISTENER_QUERY: case MLD_LISTENER_QUERY:
SCLogDebug("MLD_LISTENER_QUERY"); SCLogDebug("MLD_LISTENER_QUERY");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
if (IPV6_GET_RAW_HLIM(ip6h) != 1) { if (IPV6_GET_RAW_HLIM(ip6h) != 1) {
@ -322,7 +329,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break; break;
case MLD_LISTENER_REPORT: case MLD_LISTENER_REPORT:
SCLogDebug("MLD_LISTENER_REPORT"); SCLogDebug("MLD_LISTENER_REPORT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
if (IPV6_GET_RAW_HLIM(ip6h) != 1) { if (IPV6_GET_RAW_HLIM(ip6h) != 1) {
@ -331,7 +338,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break; break;
case MLD_LISTENER_REDUCTION: case MLD_LISTENER_REDUCTION:
SCLogDebug("MLD_LISTENER_REDUCTION"); SCLogDebug("MLD_LISTENER_REDUCTION");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
if (IPV6_GET_RAW_HLIM(ip6h) != 1) { if (IPV6_GET_RAW_HLIM(ip6h) != 1) {
@ -340,73 +347,73 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break; break;
case ICMP6_RR: case ICMP6_RR:
SCLogDebug("ICMP6_RR"); SCLogDebug("ICMP6_RR");
if (ICMPV6_GET_CODE(p) > 2 && ICMPV6_GET_CODE(p) != 255) { if (code > 2 && code != 255) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case ICMP6_NI_QUERY: case ICMP6_NI_QUERY:
SCLogDebug("ICMP6_NI_QUERY"); SCLogDebug("ICMP6_NI_QUERY");
if (ICMPV6_GET_CODE(p) > 2) { if (code > 2) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case ICMP6_NI_REPLY: case ICMP6_NI_REPLY:
SCLogDebug("ICMP6_NI_REPLY"); SCLogDebug("ICMP6_NI_REPLY");
if (ICMPV6_GET_CODE(p) > 2) { if (code > 2) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case ND_INVERSE_SOLICIT: case ND_INVERSE_SOLICIT:
SCLogDebug("ND_INVERSE_SOLICIT"); SCLogDebug("ND_INVERSE_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case ND_INVERSE_ADVERT: case ND_INVERSE_ADVERT:
SCLogDebug("ND_INVERSE_ADVERT"); SCLogDebug("ND_INVERSE_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case MLD_V2_LIST_REPORT: case MLD_V2_LIST_REPORT:
SCLogDebug("MLD_V2_LIST_REPORT"); SCLogDebug("MLD_V2_LIST_REPORT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case HOME_AGENT_AD_REQUEST: case HOME_AGENT_AD_REQUEST:
SCLogDebug("HOME_AGENT_AD_REQUEST"); SCLogDebug("HOME_AGENT_AD_REQUEST");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case HOME_AGENT_AD_REPLY: case HOME_AGENT_AD_REPLY:
SCLogDebug("HOME_AGENT_AD_REPLY"); SCLogDebug("HOME_AGENT_AD_REPLY");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case MOBILE_PREFIX_SOLICIT: case MOBILE_PREFIX_SOLICIT:
SCLogDebug("MOBILE_PREFIX_SOLICIT"); SCLogDebug("MOBILE_PREFIX_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case MOBILE_PREFIX_ADVERT: case MOBILE_PREFIX_ADVERT:
SCLogDebug("MOBILE_PREFIX_ADVERT"); SCLogDebug("MOBILE_PREFIX_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case CERT_PATH_SOLICIT: case CERT_PATH_SOLICIT:
SCLogDebug("CERT_PATH_SOLICIT"); SCLogDebug("CERT_PATH_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case CERT_PATH_ADVERT: case CERT_PATH_ADVERT:
SCLogDebug("CERT_PATH_ADVERT"); SCLogDebug("CERT_PATH_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
@ -424,40 +431,40 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break; break;
case FMIPV6_MSG: case FMIPV6_MSG:
SCLogDebug("FMIPV6_MSG"); SCLogDebug("FMIPV6_MSG");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case RPL_CONTROL_MSG: case RPL_CONTROL_MSG:
SCLogDebug("RPL_CONTROL_MSG"); SCLogDebug("RPL_CONTROL_MSG");
if (ICMPV6_GET_CODE(p) > 3 && ICMPV6_GET_CODE(p) < 128) { if (code > 3 && code < 128) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
if (ICMPV6_GET_CODE(p) > 132) { if (code > 132) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case LOCATOR_UDATE_MSG: case LOCATOR_UDATE_MSG:
SCLogDebug("LOCATOR_UDATE_MSG"); SCLogDebug("LOCATOR_UDATE_MSG");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case DUPL_ADDR_REQUEST: case DUPL_ADDR_REQUEST:
SCLogDebug("DUPL_ADDR_REQUEST"); SCLogDebug("DUPL_ADDR_REQUEST");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case DUPL_ADDR_CONFIRM: case DUPL_ADDR_CONFIRM:
SCLogDebug("DUPL_ADDR_CONFIRM"); SCLogDebug("DUPL_ADDR_CONFIRM");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
case MPL_CONTROL_MSG: case MPL_CONTROL_MSG:
SCLogDebug("MPL_CONTROL_MSG"); SCLogDebug("MPL_CONTROL_MSG");
if (ICMPV6_GET_CODE(p) != 0) { if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} }
break; break;
@ -465,21 +472,22 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
/* Various range taken from: /* Various range taken from:
* http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-2 * http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-2
*/ */
if ((ICMPV6_GET_TYPE(p) > 4) && (ICMPV6_GET_TYPE(p) < 100)) { if (type > 4 && type < 100) {
ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE); ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
} else if ((ICMPV6_GET_TYPE(p) >= 100) && (ICMPV6_GET_TYPE(p) < 102)) { } else if (type >= 100 && type < 102) {
ENGINE_SET_EVENT(p, ICMPV6_EXPERIMENTATION_TYPE); ENGINE_SET_EVENT(p, ICMPV6_EXPERIMENTATION_TYPE);
} else if ((ICMPV6_GET_TYPE(p) >= 102) && (ICMPV6_GET_TYPE(p) < 127)) { } else if (type >= 102 && type < 127) {
ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE); ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
} else if ((ICMPV6_GET_TYPE(p) >= 160) && (ICMPV6_GET_TYPE(p) < 200)) { } else if (type >= 160 && type < 200) {
ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE); ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
} else if ((ICMPV6_GET_TYPE(p) >= 200) && (ICMPV6_GET_TYPE(p) < 202)) { } else if (type >= 200 && type < 202) {
ENGINE_SET_EVENT(p, ICMPV6_EXPERIMENTATION_TYPE); ENGINE_SET_EVENT(p, ICMPV6_EXPERIMENTATION_TYPE);
} else if (ICMPV6_GET_TYPE(p) >= 202) { } else if (type >= 202) {
ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE); ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
} else { } else {
SCLogDebug("ICMPV6 Message type %" PRIu8 " not " SCLogDebug("ICMPV6 Message type %u not "
"implemented yet", ICMPV6_GET_TYPE(p)); "implemented yet",
type);
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_TYPE); ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_TYPE);
} }
} }
@ -609,13 +617,14 @@ static int ICMPV6ParamProbTest01(void)
FAIL_IF(!PacketIsICMPv6(p)); FAIL_IF(!PacketIsICMPv6(p));
/* ICMPv6 not processed at all? */ /* ICMPv6 not processed at all? */
FAIL_IF(ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0 || FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 4);
ICMPV6_GET_EMB_PROTO(p) != IPPROTO_ICMPV6); FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
FAIL_IF(ICMPV6_GET_EMB_PROTO(p) != IPPROTO_ICMPV6);
/* Let's check if we retrieved the embedded ipv6 addresses correctly */ /* Let's check if we retrieved the embedded ipv6 addresses correctly */
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
FAIL_IF(ICMPV6_GET_EMB_IPV6(p)->s_ip6_src[i] != ipv6src[i] || FAIL_IF(PacketGetICMPv6EmbIPv6(p)->s_ip6_src[i] != ipv6src[i] ||
ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst[i] != ipv6dst[i]); PacketGetICMPv6EmbIPv6(p)->s_ip6_dst[i] != ipv6dst[i]);
} }
PacketRecycle(p); PacketRecycle(p);
@ -664,12 +673,13 @@ static int ICMPV6PktTooBigTest01(void)
/* Note: it has an embedded ipv6 packet but no protocol after ipv6 /* Note: it has an embedded ipv6 packet but no protocol after ipv6
* (IPPROTO_NONE) */ * (IPPROTO_NONE) */
/* Check if ICMPv6 header was processed at all. */ /* Check if ICMPv6 header was processed at all. */
FAIL_IF(ICMPV6_GET_TYPE(p) != 2 || ICMPV6_GET_CODE(p) != 0 ); FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 2);
FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
/* Let's check if we retrieved the embedded ipv6 addresses correctly */ /* Let's check if we retrieved the embedded ipv6 addresses correctly */
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
FAIL_IF(ICMPV6_GET_EMB_IPV6(p)->s_ip6_src[i] != ipv6src[i] || FAIL_IF(PacketGetICMPv6EmbIPv6(p)->s_ip6_src[i] != ipv6src[i] ||
ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst[i] != ipv6dst[i]); PacketGetICMPv6EmbIPv6(p)->s_ip6_dst[i] != ipv6dst[i]);
} }
SCLogDebug("ICMPV6 IPV6 src and dst properly set"); SCLogDebug("ICMPV6 IPV6 src and dst properly set");
@ -718,14 +728,15 @@ static int ICMPV6TimeExceedTest01(void)
FAIL_IF(!PacketIsICMPv6(p)); FAIL_IF(!PacketIsICMPv6(p));
/* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */ /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */
FAIL_IF(ICMPV6_GET_TYPE(p) != 3 || ICMPV6_GET_CODE(p) != 0 || FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 3);
ICMPV6_GET_EMB_IPV6(p) == NULL || FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE); FAIL_IF_NULL(PacketGetICMPv6EmbIPv6(p));
FAIL_IF(ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE);
/* Let's check if we retrieved the embedded ipv6 addresses correctly */ /* Let's check if we retrieved the embedded ipv6 addresses correctly */
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
FAIL_IF(ICMPV6_GET_EMB_IPV6(p)->s_ip6_src[i] != ipv6src[i] || FAIL_IF(PacketGetICMPv6EmbIPv6(p)->s_ip6_src[i] != ipv6src[i] ||
ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst[i] != ipv6dst[i]); PacketGetICMPv6EmbIPv6(p)->s_ip6_dst[i] != ipv6dst[i]);
} }
SCLogDebug("ICMPV6 IPV6 src and dst properly set"); SCLogDebug("ICMPV6 IPV6 src and dst properly set");
@ -774,14 +785,15 @@ static int ICMPV6DestUnreachTest01(void)
FAIL_IF(!PacketIsICMPv6(p)); FAIL_IF(!PacketIsICMPv6(p));
/* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */ /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */
FAIL_IF(ICMPV6_GET_TYPE(p) != 1 || ICMPV6_GET_CODE(p) != 0 || FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 1);
ICMPV6_GET_EMB_IPV6(p) == NULL || FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE); FAIL_IF_NULL(PacketGetICMPv6EmbIPv6(p));
FAIL_IF(ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE);
/* Let's check if we retrieved the embedded ipv6 addresses correctly */ /* Let's check if we retrieved the embedded ipv6 addresses correctly */
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
FAIL_IF(ICMPV6_GET_EMB_IPV6(p)->s_ip6_src[i] != ipv6src[i] || FAIL_IF(PacketGetICMPv6EmbIPv6(p)->s_ip6_src[i] != ipv6src[i] ||
ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst[i] != ipv6dst[i]); PacketGetICMPv6EmbIPv6(p)->s_ip6_dst[i] != ipv6dst[i]);
} }
PacketRecycle(p); PacketRecycle(p);
@ -819,13 +831,10 @@ static int ICMPV6EchoReqTest01(void)
SCLogDebug("ID: %u seq: %u", ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); SCLogDebug("ID: %u seq: %u", ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p));
if (ICMPV6_GET_TYPE(p) != 128 || ICMPV6_GET_CODE(p) != 0 || FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 128);
SCNtohs(ICMPV6_GET_ID(p)) != 9712 || SCNtohs(ICMPV6_GET_SEQ(p)) != 29987) { FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
printf("ICMPv6 Echo reply decode failed TYPE %u CODE %u ID %04x(%u) SEQ %04x(%u): ", FAIL_IF(SCNtohs(ICMPV6_GET_ID(p)) != 9712);
ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), SCNtohs(ICMPV6_GET_ID(p)), FAIL_IF(SCNtohs(ICMPV6_GET_SEQ(p)) != 29987);
ICMPV6_GET_SEQ(p), SCNtohs(ICMPV6_GET_SEQ(p)));
FAIL;
}
PacketRecycle(p); PacketRecycle(p);
FlowShutdown(); FlowShutdown();
@ -861,16 +870,10 @@ static int ICMPV6EchoRepTest01(void)
DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
FAIL_IF(!PacketIsICMPv6(p)); FAIL_IF(!PacketIsICMPv6(p));
SCLogDebug("type: %u code %u ID: %u seq: %u", ICMPV6_GET_TYPE(p), FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 129);
ICMPV6_GET_CODE(p),ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
FAIL_IF(SCNtohs(ICMPV6_GET_ID(p)) != 9712);
if (ICMPV6_GET_TYPE(p) != 129 || ICMPV6_GET_CODE(p) != 0 || FAIL_IF(SCNtohs(ICMPV6_GET_SEQ(p)) != 29987);
SCNtohs(ICMPV6_GET_ID(p)) != 9712 || SCNtohs(ICMPV6_GET_SEQ(p)) != 29987) {
printf("ICMPv6 Echo reply decode failed TYPE %u CODE %u ID %04x(%u) SEQ %04x(%u): ",
ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), SCNtohs(ICMPV6_GET_ID(p)),
ICMPV6_GET_SEQ(p), SCNtohs(ICMPV6_GET_SEQ(p)));
FAIL;
}
PacketRecycle(p); PacketRecycle(p);
FlowShutdown(); FlowShutdown();
@ -911,7 +914,8 @@ static int ICMPV6ParamProbTest02(void)
FlowInitConfig(FLOW_QUIET); FlowInitConfig(FLOW_QUIET);
DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6)); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
FAIL_IF(!PacketIsICMPv6(p)); FAIL_IF(!PacketIsICMPv6(p));
FAIL_IF(ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0); FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 4);
FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER)); FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER));
PacketRecycle(p); PacketRecycle(p);
@ -1501,19 +1505,19 @@ static int ICMPV6CalculateValidChecksumWithFCS(void)
FAIL_IF_NULL(p); FAIL_IF_NULL(p);
ThreadVars tv; ThreadVars tv;
DecodeThreadVars dtv; DecodeThreadVars dtv;
memset(&tv, 0, sizeof(ThreadVars)); memset(&tv, 0, sizeof(ThreadVars));
memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&dtv, 0, sizeof(DecodeThreadVars));
FlowInitConfig(FLOW_QUIET); FlowInitConfig(FLOW_QUIET);
DecodeIPV6(&tv, &dtv, p, raw_ipv6 + 14, sizeof(raw_ipv6) - 14); DecodeEthernet(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
FAIL_IF(!PacketIsICMPv6(p)); FAIL_IF(!PacketIsICMPv6(p));
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
const IPV6Hdr *ip6h = PacketGetIPv6(p); const IPV6Hdr *ip6h = PacketGetIPv6(p);
uint16_t icmpv6_len = IPV6_GET_RAW_PLEN(ip6h) - uint16_t icmpv6_len = IPV6_GET_RAW_PLEN(ip6h) -
((const uint8_t *)p->icmpv6h - (const uint8_t *)ip6h - IPV6_HEADER_LEN); ((const uint8_t *)icmpv6h - (const uint8_t *)ip6h - IPV6_HEADER_LEN);
FAIL_IF(icmpv6_len != 28); FAIL_IF(icmpv6_len != 28);
FAIL_IF(ICMPV6CalculateChecksum(ip6h->s_ip6_addrs, (uint16_t *)p->icmpv6h, icmpv6_len) != csum); FAIL_IF(ICMPV6CalculateChecksum(ip6h->s_ip6_addrs, (uint16_t *)icmpv6h, icmpv6_len) != csum);
PacketRecycle(p); PacketRecycle(p);
FlowShutdown(); FlowShutdown();

@ -98,32 +98,25 @@
/** macro for icmpv6 "type" access */ /** macro for icmpv6 "type" access */
#define ICMPV6_GET_TYPE(p) (p)->icmpv6h->type #define ICMPV6_GET_TYPE(icmp6h) (icmp6h)->type
/** macro for icmpv6 "code" access */ /** macro for icmpv6 "code" access */
#define ICMPV6_GET_CODE(p) (p)->icmpv6h->code #define ICMPV6_GET_CODE(icmp6h) (icmp6h)->code
/** macro for icmpv6 "csum" access */
#define ICMPV6_GET_RAW_CSUM(p) SCNtohs((p)->icmpv6h->csum)
#define ICMPV6_GET_CSUM(p) (p)->icmpv6h->csum
/** If message is informational */ /** If message is informational */
/** macro for icmpv6 "id" access */ /** macro for icmpv6 "id" access */
#define ICMPV6_GET_ID(p) (p)->icmpv6vars.id #define ICMPV6_GET_ID(p) (p)->l4.vars.icmpv6.id
/** macro for icmpv6 "seq" access */ /** macro for icmpv6 "seq" access */
#define ICMPV6_GET_SEQ(p) (p)->icmpv6vars.seq #define ICMPV6_GET_SEQ(p) (p)->l4.vars.icmpv6.seq
/** If message is Error */ /** If message is Error */
/** macro for icmpv6 "unused" access */
#define ICMPV6_GET_UNUSED(p) (p)->icmpv6h->icmpv6b.icmpv6e.unused
/** macro for icmpv6 "mtu" accessibility */ /** macro for icmpv6 "mtu" accessibility */
// ICMPv6 has MTU only for type too big // ICMPv6 has MTU only for type too big
#define ICMPV6_HAS_MTU(p) ((p)->icmpv6h->type == ICMP6_PACKET_TOO_BIG) #define ICMPV6_HAS_MTU(icmp6h) ((icmp6h)->type == ICMP6_PACKET_TOO_BIG)
/** macro for icmpv6 "mtu" access */ /** macro for icmpv6 "mtu" access */
#define ICMPV6_GET_MTU(p) SCNtohl((p)->icmpv6h->icmpv6b.icmpv6e.mtu) #define ICMPV6_GET_MTU(icmp6h) SCNtohl((icmp6h)->icmpv6b.icmpv6e.mtu)
/** macro for icmpv6 embedded "protocol" access */ /** macro for icmpv6 embedded "protocol" access */
#define ICMPV6_GET_EMB_PROTO(p) (p)->icmpv6vars.emb_ip6_proto_next #define ICMPV6_GET_EMB_PROTO(p) (p)->l4.vars.icmpv6.emb_ip6_proto_next
/** macro for icmpv6 embedded "ipv6h" header access */
#define ICMPV6_GET_EMB_IPV6(p) (p)->icmpv6vars.emb_ipv6h
typedef struct ICMPV6Info_ typedef struct ICMPV6Info_
{ {
@ -167,12 +160,6 @@ typedef struct ICMPV6Vars_ {
IPV6Hdr *emb_ipv6h; IPV6Hdr *emb_ipv6h;
} ICMPV6Vars; } ICMPV6Vars;
#define CLEAR_ICMPV6_PACKET(p) \
do { \
PACKET_CLEAR_L4VARS((p)); \
(p)->icmpv6h = NULL; \
} while (0)
void DecodeICMPV6RegisterTests(void); void DecodeICMPV6RegisterTests(void);
int ICMPv6GetCounterpart(uint8_t type); int ICMPv6GetCounterpart(uint8_t type);

@ -428,6 +428,7 @@ struct PacketL3 {
enum PacketL4Types { enum PacketL4Types {
PACKET_L4_UNKNOWN = 0, PACKET_L4_UNKNOWN = 0,
PACKET_L4_ICMPV6,
PACKET_L4_SCTP, PACKET_L4_SCTP,
PACKET_L4_GRE, PACKET_L4_GRE,
PACKET_L4_ESP, PACKET_L4_ESP,
@ -438,10 +439,14 @@ struct PacketL4 {
bool csum_set; bool csum_set;
uint16_t csum; uint16_t csum;
union L4Hdrs { union L4Hdrs {
ICMPV6Hdr *icmpv6h;
SCTPHdr *sctph; SCTPHdr *sctph;
GREHdr *greh; GREHdr *greh;
ESPHdr *esph; ESPHdr *esph;
} hdrs; } hdrs;
union L4Vars {
ICMPV6Vars icmpv6;
} vars;
}; };
/* sizes of the members: /* sizes of the members:
@ -571,16 +576,13 @@ typedef struct Packet_
union { union {
TCPVars tcpvars; TCPVars tcpvars;
ICMPV4Vars icmpv4vars; ICMPV4Vars icmpv4vars;
ICMPV6Vars icmpv6vars;
} l4vars; } l4vars;
#define tcpvars l4vars.tcpvars #define tcpvars l4vars.tcpvars
#define icmpv4vars l4vars.icmpv4vars #define icmpv4vars l4vars.icmpv4vars
#define icmpv6vars l4vars.icmpv6vars
TCPHdr *tcph; TCPHdr *tcph;
UDPHdr *udph; UDPHdr *udph;
ICMPV4Hdr *icmpv4h; ICMPV4Hdr *icmpv4h;
ICMPV6Hdr *icmpv6h;
PPPOESessionHdr *pppoesh; PPPOESessionHdr *pppoesh;
PPPOEDiscoveryHdr *pppoedh; PPPOEDiscoveryHdr *pppoedh;
@ -773,9 +775,23 @@ static inline bool PacketIsICMPv4(const Packet *p)
return PKT_IS_ICMPV4(p); return PKT_IS_ICMPV4(p);
} }
static inline ICMPV6Hdr *PacketSetICMPv6(Packet *p, const uint8_t *buf)
{
DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_UNKNOWN);
p->l4.type = PACKET_L4_ICMPV6;
p->l4.hdrs.icmpv6h = (ICMPV6Hdr *)buf;
return p->l4.hdrs.icmpv6h;
}
static inline const ICMPV6Hdr *PacketGetICMPv6(const Packet *p)
{
DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_ICMPV6);
return p->l4.hdrs.icmpv6h;
}
static inline bool PacketIsICMPv6(const Packet *p) static inline bool PacketIsICMPv6(const Packet *p)
{ {
return PKT_IS_ICMPV6(p); return p->l4.type == PACKET_L4_ICMPV6;
} }
static inline SCTPHdr *PacketSetSCTP(Packet *p, const uint8_t *buf) static inline SCTPHdr *PacketSetSCTP(Packet *p, const uint8_t *buf)

@ -776,8 +776,11 @@ static int DetectICMPV6CsumMatch(DetectEngineThreadCtx *det_ctx,
const DetectCsumData *cd = (const DetectCsumData *)ctx; const DetectCsumData *cd = (const DetectCsumData *)ctx;
if (!PacketIsIPv6(p) || !PacketIsICMPv6(p) || p->proto != IPPROTO_ICMPV6 || if (!PacketIsIPv6(p) || !PacketIsICMPv6(p) || p->proto != IPPROTO_ICMPV6 ||
PKT_IS_PSEUDOPKT(p) || PKT_IS_PSEUDOPKT(p)) {
(GET_PKT_LEN(p) - ((uint8_t *)p->icmpv6h - GET_PKT_DATA(p))) <= 0) { return 0;
}
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
if ((GET_PKT_LEN(p) - ((uint8_t *)icmpv6h - GET_PKT_DATA(p))) <= 0) {
return 0; return 0;
} }
@ -788,14 +791,14 @@ static int DetectICMPV6CsumMatch(DetectEngineThreadCtx *det_ctx,
if (!p->l4.csum_set) { if (!p->l4.csum_set) {
const IPV6Hdr *ip6h = PacketGetIPv6(p); const IPV6Hdr *ip6h = PacketGetIPv6(p);
uint16_t len = IPV6_GET_RAW_PLEN(ip6h) - uint16_t len = IPV6_GET_RAW_PLEN(ip6h) -
(uint16_t)((uint8_t *)p->icmpv6h - (uint8_t *)ip6h - IPV6_HEADER_LEN); (uint16_t)((uint8_t *)icmpv6h - (uint8_t *)ip6h - IPV6_HEADER_LEN);
p->l4.csum = ICMPV6CalculateChecksum(ip6h->s_ip6_addrs, (uint16_t *)p->icmpv6h, len); p->l4.csum = ICMPV6CalculateChecksum(ip6h->s_ip6_addrs, (uint16_t *)icmpv6h, len);
p->l4.csum_set = true; p->l4.csum_set = true;
} }
if (p->l4.csum == p->icmpv6h->csum && cd->valid == 1) if (p->l4.csum == icmpv6h->csum && cd->valid == 1)
return 1; return 1;
else if (p->l4.csum != p->icmpv6h->csum && cd->valid == 0) else if (p->l4.csum != icmpv6h->csum && cd->valid == 0)
return 1; return 1;
else else
return 0; return 0;

@ -100,7 +100,7 @@ static inline bool GetIcmpId(Packet *p, uint16_t *id)
return false; return false;
} }
} else if (PacketIsICMPv6(p)) { } else if (PacketIsICMPv6(p)) {
switch (ICMPV6_GET_TYPE(p)) { switch (ICMPV6_GET_TYPE(PacketGetICMPv6(p))) {
case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REQUEST:
case ICMP6_ECHO_REPLY: case ICMP6_ECHO_REPLY:
SCLogDebug("ICMPV6_GET_ID(p) %"PRIu16" (network byte order), " SCLogDebug("ICMPV6_GET_ID(p) %"PRIu16" (network byte order), "

@ -100,8 +100,7 @@ static inline bool GetIcmpSeq(Packet *p, uint16_t *seq)
return false; return false;
} }
} else if (PacketIsICMPv6(p)) { } else if (PacketIsICMPv6(p)) {
switch (ICMPV6_GET_TYPE(PacketGetICMPv6(p))) {
switch (ICMPV6_GET_TYPE(p)) {
case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REQUEST:
case ICMP6_ECHO_REPLY: case ICMP6_ECHO_REPLY:
SCLogDebug("ICMPV6_GET_SEQ(p) %"PRIu16" (network byte order), " SCLogDebug("ICMPV6_GET_SEQ(p) %"PRIu16" (network byte order), "

@ -66,12 +66,13 @@ static inline int DetectICMPv6mtuGetValue(Packet *p, uint32_t *picmpv6mtu)
{ {
if (!(PacketIsICMPv6(p)) || PKT_IS_PSEUDOPKT(p)) if (!(PacketIsICMPv6(p)) || PKT_IS_PSEUDOPKT(p))
return 0; return 0;
if (ICMPV6_GET_CODE(p) != 0) const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
if (ICMPV6_GET_CODE(icmpv6h) != 0)
return 0; return 0;
if (!(ICMPV6_HAS_MTU(p))) if (!(ICMPV6_HAS_MTU(icmpv6h)))
return 0; return 0;
*picmpv6mtu = ICMPV6_GET_MTU(p); *picmpv6mtu = ICMPV6_GET_MTU(icmpv6h);
return 1; return 1;
} }

@ -109,17 +109,16 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
// DETECT_PROTO_IPV6 does not prefilter // DETECT_PROTO_IPV6 does not prefilter
return NULL; return NULL;
} }
if (((uint8_t *)p->icmpv6h + (ptrdiff_t)hlen) > const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) if (((uint8_t *)icmpv6h + (ptrdiff_t)hlen) >
{ ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) {
SCLogDebug("data out of range: %p > %p", SCLogDebug("data out of range: %p > %p", ((uint8_t *)icmpv6h + (ptrdiff_t)hlen),
((uint8_t *)p->icmpv6h + (ptrdiff_t)hlen),
((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))); ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p)));
SCReturnPtr(NULL, "InspectionBuffer"); SCReturnPtr(NULL, "InspectionBuffer");
} }
const uint32_t data_len = hlen; const uint32_t data_len = hlen;
const uint8_t *data = (const uint8_t *)p->icmpv6h; const uint8_t *data = (const uint8_t *)icmpv6h;
InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len);
InspectionBufferApplyTransforms(buffer, transforms); InspectionBufferApplyTransforms(buffer, transforms);

@ -94,7 +94,8 @@ static int DetectICodeMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
if (PacketIsICMPv4(p)) { if (PacketIsICMPv4(p)) {
picode = ICMPV4_GET_CODE(p); picode = ICMPV4_GET_CODE(p);
} else if (PacketIsICMPv6(p)) { } else if (PacketIsICMPv6(p)) {
picode = ICMPV6_GET_CODE(p); const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
picode = ICMPV6_GET_CODE(icmpv6h);
} else { } else {
/* Packet not ICMPv4 nor ICMPv6 */ /* Packet not ICMPv4 nor ICMPv6 */
return 0; return 0;
@ -159,7 +160,8 @@ static void PrefilterPacketICodeMatch(DetectEngineThreadCtx *det_ctx,
if (PacketIsICMPv4(p)) { if (PacketIsICMPv4(p)) {
picode = ICMPV4_GET_CODE(p); picode = ICMPV4_GET_CODE(p);
} else if (PacketIsICMPv6(p)) { } else if (PacketIsICMPv6(p)) {
picode = ICMPV6_GET_CODE(p); const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
picode = ICMPV6_GET_CODE(icmpv6h);
} else { } else {
/* Packet not ICMPv4 nor ICMPv6 */ /* Packet not ICMPv4 nor ICMPv6 */
return; return;

@ -91,7 +91,8 @@ static int DetectITypeMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
if (PacketIsICMPv4(p)) { if (PacketIsICMPv4(p)) {
pitype = ICMPV4_GET_TYPE(p); pitype = ICMPV4_GET_TYPE(p);
} else if (PacketIsICMPv6(p)) { } else if (PacketIsICMPv6(p)) {
pitype = ICMPV6_GET_TYPE(p); const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
pitype = ICMPV6_GET_TYPE(icmpv6h);
} else { } else {
/* Packet not ICMPv4 nor ICMPv6 */ /* Packet not ICMPv4 nor ICMPv6 */
return 0; return 0;
@ -175,7 +176,8 @@ static void PrefilterPacketITypeMatch(DetectEngineThreadCtx *det_ctx,
if (PacketIsICMPv4(p)) { if (PacketIsICMPv4(p)) {
pitype = ICMPV4_GET_TYPE(p); pitype = ICMPV4_GET_TYPE(p);
} else if (PacketIsICMPv6(p)) { } else if (PacketIsICMPv6(p)) {
pitype = ICMPV6_GET_TYPE(p); const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
pitype = ICMPV6_GET_TYPE(icmpv6h);
} else { } else {
/* Packet not ICMPv4 nor ICMPv6 */ /* Packet not ICMPv4 nor ICMPv6 */
return; return;

@ -845,9 +845,9 @@ JsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir,
} }
break; break;
case IPPROTO_ICMPV6: case IPPROTO_ICMPV6:
if (p->icmpv6h) { if (PacketIsICMPv6(p)) {
jb_set_uint(js, "icmp_type", p->icmpv6h->type); jb_set_uint(js, "icmp_type", PacketGetICMPv6(p)->type);
jb_set_uint(js, "icmp_code", p->icmpv6h->code); jb_set_uint(js, "icmp_code", PacketGetICMPv6(p)->code);
} }
break; break;
} }

@ -124,9 +124,6 @@ void PacketReinit(Packet *p)
if (p->icmpv4h != NULL) { if (p->icmpv4h != NULL) {
CLEAR_ICMPV4_PACKET(p); CLEAR_ICMPV4_PACKET(p);
} }
if (p->icmpv6h != NULL) {
CLEAR_ICMPV6_PACKET(p);
}
p->pppoesh = NULL; p->pppoesh = NULL;
p->pppoedh = NULL; p->pppoedh = NULL;
p->payload = NULL; p->payload = NULL;

@ -366,7 +366,7 @@ static void DPDKReleasePacket(Packet *p)
if ((p->dpdk_v.copy_mode == DPDK_COPY_MODE_TAP || if ((p->dpdk_v.copy_mode == DPDK_COPY_MODE_TAP ||
(p->dpdk_v.copy_mode == DPDK_COPY_MODE_IPS && !PacketCheckAction(p, ACTION_DROP))) (p->dpdk_v.copy_mode == DPDK_COPY_MODE_IPS && !PacketCheckAction(p, ACTION_DROP)))
#if defined(RTE_LIBRTE_I40E_PMD) || defined(RTE_LIBRTE_IXGBE_PMD) || defined(RTE_LIBRTE_ICE_PMD) #if defined(RTE_LIBRTE_I40E_PMD) || defined(RTE_LIBRTE_IXGBE_PMD) || defined(RTE_LIBRTE_ICE_PMD)
&& !(PacketIsICMPv6(p) && p->icmpv6h->type == 143) && !(PacketIsICMPv6(p) && PacketGetICMPv6(p)->type == 143)
#endif #endif
) { ) {
BUG_ON(PKT_IS_PSEUDOPKT(p)); BUG_ON(PKT_IS_PSEUDOPKT(p));

@ -81,7 +81,7 @@
} else if ((p)->proto == IPPROTO_SCTP) { \ } else if ((p)->proto == IPPROTO_SCTP) { \
BUG_ON(PacketGetSCTP((p)) == NULL); \ BUG_ON(PacketGetSCTP((p)) == NULL); \
} else if ((p)->proto == IPPROTO_ICMPV6) { \ } else if ((p)->proto == IPPROTO_ICMPV6) { \
BUG_ON((p)->icmpv6h == NULL); \ BUG_ON(PacketGetICMPv6((p)) == NULL); \
} \ } \
} \ } \
if ((p)->payload_len > 0) { \ if ((p)->payload_len > 0) { \

Loading…
Cancel
Save