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-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
*
@ -66,51 +74,51 @@ static void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len )
return;
}
/** We need to fill icmpv6vars */
p->icmpv6vars.emb_ipv6h = icmp6_ip6h;
/** We need to fill l4.vars.icmpv6 */
p->l4.vars.icmpv6.emb_ipv6h = icmp6_ip6h;
/** 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) {
case IPPROTO_TCP:
if (len >= IPV6_HEADER_LEN + TCP_HEADER_LEN ) {
TCPHdr *emb_tcph = (TCPHdr *)(partial_packet + IPV6_HEADER_LEN);
p->icmpv6vars.emb_sport = emb_tcph->th_sport;
p->icmpv6vars.emb_dport = emb_tcph->th_dport;
p->icmpv6vars.emb_ports_set = true;
p->l4.vars.icmpv6.emb_sport = emb_tcph->th_sport;
p->l4.vars.icmpv6.emb_dport = emb_tcph->th_dport;
p->l4.vars.icmpv6.emb_ports_set = true;
SCLogDebug("ICMPV6->IPV6->TCP header sport: "
"%"PRIu16" dport %"PRIu16"", p->icmpv6vars.emb_sport,
p->icmpv6vars.emb_dport);
"%" PRIu16 " dport %" PRIu16 "",
p->l4.vars.icmpv6.emb_sport, p->l4.vars.icmpv6.emb_dport);
} else {
SCLogDebug("Warning, ICMPV6->IPV6->TCP "
"header Didn't fit in the packet!");
p->icmpv6vars.emb_sport = 0;
p->icmpv6vars.emb_dport = 0;
p->l4.vars.icmpv6.emb_sport = 0;
p->l4.vars.icmpv6.emb_dport = 0;
}
break;
case IPPROTO_UDP:
if (len >= IPV6_HEADER_LEN + UDP_HEADER_LEN ) {
UDPHdr *emb_udph = (UDPHdr *)(partial_packet + IPV6_HEADER_LEN);
p->icmpv6vars.emb_sport = emb_udph->uh_sport;
p->icmpv6vars.emb_dport = emb_udph->uh_dport;
p->icmpv6vars.emb_ports_set = true;
p->l4.vars.icmpv6.emb_sport = emb_udph->uh_sport;
p->l4.vars.icmpv6.emb_dport = emb_udph->uh_dport;
p->l4.vars.icmpv6.emb_ports_set = true;
SCLogDebug("ICMPV6->IPV6->UDP header sport: "
"%"PRIu16" dport %"PRIu16"", p->icmpv6vars.emb_sport,
p->icmpv6vars.emb_dport);
"%" PRIu16 " dport %" PRIu16 "",
p->l4.vars.icmpv6.emb_sport, p->l4.vars.icmpv6.emb_dport);
} else {
SCLogDebug("Warning, ICMPV6->IPV6->UDP "
"header Didn't fit in the packet!");
p->icmpv6vars.emb_sport = 0;
p->icmpv6vars.emb_dport = 0;
p->l4.vars.icmpv6.emb_sport = 0;
p->l4.vars.icmpv6.emb_dport = 0;
}
break;
case IPPROTO_ICMPV6:
p->icmpv6vars.emb_sport = 0;
p->icmpv6vars.emb_dport = 0;
p->l4.vars.icmpv6.emb_sport = 0;
p->l4.vars.icmpv6.emb_dport = 0;
SCLogDebug("ICMPV6->IPV6->ICMP header");
@ -120,8 +128,8 @@ static void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len )
/* debug print */
#ifdef DEBUG
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 *)ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst, d, sizeof(d));
PrintInet(AF_INET6, (const void *)PacketGetICMPv6EmbIPv6(p)->s_ip6_src, s, sizeof(s));
PrintInet(AF_INET6, (const void *)PacketGetICMPv6EmbIPv6(p)->s_ip6_dst, d, sizeof(d));
SCLogDebug("ICMPv6 embedding IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: "
"%" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32,
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;
}
p->icmpv6h = (ICMPV6Hdr *)pkt;
ICMPV6Hdr *icmpv6h = PacketSetICMPv6(p, pkt);
p->proto = IPPROTO_ICMPV6;
p->icmp_s.type = p->icmpv6h->type;
p->icmp_s.code = p->icmpv6h->code;
const uint8_t type = p->icmp_s.type = icmpv6h->type;
const uint8_t code = p->icmp_s.code = icmpv6h->code;
DEBUG_VALIDATE_BUG_ON(len - ICMPV6_HEADER_LEN > UINT16_MAX);
p->payload_len = (uint16_t)(len - 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;
}
SCLogDebug("ICMPV6 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv6h->type,
p->icmpv6h->code);
SCLogDebug("ICMPV6 TYPE %u CODE %u", type, code);
switch (ICMPV6_GET_TYPE(p)) {
switch (type) {
case 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);
} else {
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:
SCLogDebug("ICMP6_PACKET_TOO_BIG");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else {
if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
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),
(uint16_t)(len - ICMPV6_HEADER_LEN));
full_hdr = 1;
@ -228,7 +235,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
case 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);
} else {
if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
@ -243,7 +250,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
case 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);
} else {
if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
@ -256,64 +263,64 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break;
case ICMP6_ECHO_REQUEST:
SCLogDebug("ICMP6_ECHO_REQUEST id: %u seq: %u",
p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq);
SCLogDebug("ICMP6_ECHO_REQUEST id: %u seq: %u", icmpv6h->icmpv6b.icmpv6i.id,
icmpv6h->icmpv6b.icmpv6i.seq);
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else {
p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id;
p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq;
p->l4.vars.icmpv6.id = icmpv6h->icmpv6b.icmpv6i.id;
p->l4.vars.icmpv6.seq = icmpv6h->icmpv6b.icmpv6i.seq;
full_hdr = 1;
}
break;
case ICMP6_ECHO_REPLY:
SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u",
p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq);
SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u", icmpv6h->icmpv6b.icmpv6i.id,
icmpv6h->icmpv6b.icmpv6i.seq);
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else {
p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id;
p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq;
p->l4.vars.icmpv6.id = icmpv6h->icmpv6b.icmpv6i.id;
p->l4.vars.icmpv6.seq = icmpv6h->icmpv6b.icmpv6i.seq;
full_hdr = 1;
}
break;
case ND_ROUTER_SOLICIT:
SCLogDebug("ND_ROUTER_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_ROUTER_ADVERT:
SCLogDebug("ND_ROUTER_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_NEIGHBOR_SOLICIT:
SCLogDebug("ND_NEIGHBOR_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_NEIGHBOR_ADVERT:
SCLogDebug("ND_NEIGHBOR_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_REDIRECT:
SCLogDebug("ND_REDIRECT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case MLD_LISTENER_QUERY:
SCLogDebug("MLD_LISTENER_QUERY");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
if (IPV6_GET_RAW_HLIM(ip6h) != 1) {
@ -322,7 +329,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break;
case MLD_LISTENER_REPORT:
SCLogDebug("MLD_LISTENER_REPORT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
if (IPV6_GET_RAW_HLIM(ip6h) != 1) {
@ -331,7 +338,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break;
case MLD_LISTENER_REDUCTION:
SCLogDebug("MLD_LISTENER_REDUCTION");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
if (IPV6_GET_RAW_HLIM(ip6h) != 1) {
@ -340,73 +347,73 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break;
case 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);
}
break;
case ICMP6_NI_QUERY:
SCLogDebug("ICMP6_NI_QUERY");
if (ICMPV6_GET_CODE(p) > 2) {
if (code > 2) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ICMP6_NI_REPLY:
SCLogDebug("ICMP6_NI_REPLY");
if (ICMPV6_GET_CODE(p) > 2) {
if (code > 2) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_INVERSE_SOLICIT:
SCLogDebug("ND_INVERSE_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_INVERSE_ADVERT:
SCLogDebug("ND_INVERSE_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case 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);
}
break;
case 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);
}
break;
case 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);
}
break;
case MOBILE_PREFIX_SOLICIT:
SCLogDebug("MOBILE_PREFIX_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case MOBILE_PREFIX_ADVERT:
SCLogDebug("MOBILE_PREFIX_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case CERT_PATH_SOLICIT:
SCLogDebug("CERT_PATH_SOLICIT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case CERT_PATH_ADVERT:
SCLogDebug("CERT_PATH_ADVERT");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
@ -424,40 +431,40 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
break;
case FMIPV6_MSG:
SCLogDebug("FMIPV6_MSG");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case 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);
}
if (ICMPV6_GET_CODE(p) > 132) {
if (code > 132) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case LOCATOR_UDATE_MSG:
SCLogDebug("LOCATOR_UDATE_MSG");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case DUPL_ADDR_REQUEST:
SCLogDebug("DUPL_ADDR_REQUEST");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case DUPL_ADDR_CONFIRM:
SCLogDebug("DUPL_ADDR_CONFIRM");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case MPL_CONTROL_MSG:
SCLogDebug("MPL_CONTROL_MSG");
if (ICMPV6_GET_CODE(p) != 0) {
if (code != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
@ -465,21 +472,22 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
/* Various range taken from:
* 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);
} 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);
} 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);
} 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);
} 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);
} else if (ICMPV6_GET_TYPE(p) >= 202) {
} else if (type >= 202) {
ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
} else {
SCLogDebug("ICMPV6 Message type %" PRIu8 " not "
"implemented yet", ICMPV6_GET_TYPE(p));
SCLogDebug("ICMPV6 Message type %u not "
"implemented yet",
type);
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_TYPE);
}
}
@ -609,13 +617,14 @@ static int ICMPV6ParamProbTest01(void)
FAIL_IF(!PacketIsICMPv6(p));
/* ICMPv6 not processed at all? */
FAIL_IF(ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0 ||
ICMPV6_GET_EMB_PROTO(p) != IPPROTO_ICMPV6);
FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 4);
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 */
for (int i = 0; i < 4; i++) {
FAIL_IF(ICMPV6_GET_EMB_IPV6(p)->s_ip6_src[i] != ipv6src[i] ||
ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst[i] != ipv6dst[i]);
FAIL_IF(PacketGetICMPv6EmbIPv6(p)->s_ip6_src[i] != ipv6src[i] ||
PacketGetICMPv6EmbIPv6(p)->s_ip6_dst[i] != ipv6dst[i]);
}
PacketRecycle(p);
@ -664,12 +673,13 @@ static int ICMPV6PktTooBigTest01(void)
/* Note: it has an embedded ipv6 packet but no protocol after ipv6
* (IPPROTO_NONE) */
/* 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 */
for (int i = 0; i < 4; i++) {
FAIL_IF(ICMPV6_GET_EMB_IPV6(p)->s_ip6_src[i] != ipv6src[i] ||
ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst[i] != ipv6dst[i]);
FAIL_IF(PacketGetICMPv6EmbIPv6(p)->s_ip6_src[i] != ipv6src[i] ||
PacketGetICMPv6EmbIPv6(p)->s_ip6_dst[i] != ipv6dst[i]);
}
SCLogDebug("ICMPV6 IPV6 src and dst properly set");
@ -718,14 +728,15 @@ static int ICMPV6TimeExceedTest01(void)
FAIL_IF(!PacketIsICMPv6(p));
/* 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 ||
ICMPV6_GET_EMB_IPV6(p) == NULL ||
ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE);
FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 3);
FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
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 */
for (int i = 0; i < 4; i++) {
FAIL_IF(ICMPV6_GET_EMB_IPV6(p)->s_ip6_src[i] != ipv6src[i] ||
ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst[i] != ipv6dst[i]);
FAIL_IF(PacketGetICMPv6EmbIPv6(p)->s_ip6_src[i] != ipv6src[i] ||
PacketGetICMPv6EmbIPv6(p)->s_ip6_dst[i] != ipv6dst[i]);
}
SCLogDebug("ICMPV6 IPV6 src and dst properly set");
@ -774,14 +785,15 @@ static int ICMPV6DestUnreachTest01(void)
FAIL_IF(!PacketIsICMPv6(p));
/* 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 ||
ICMPV6_GET_EMB_IPV6(p) == NULL ||
ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE);
FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 1);
FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
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 */
for (int i = 0; i < 4; i++) {
FAIL_IF(ICMPV6_GET_EMB_IPV6(p)->s_ip6_src[i] != ipv6src[i] ||
ICMPV6_GET_EMB_IPV6(p)->s_ip6_dst[i] != ipv6dst[i]);
FAIL_IF(PacketGetICMPv6EmbIPv6(p)->s_ip6_src[i] != ipv6src[i] ||
PacketGetICMPv6EmbIPv6(p)->s_ip6_dst[i] != ipv6dst[i]);
}
PacketRecycle(p);
@ -819,13 +831,10 @@ static int ICMPV6EchoReqTest01(void)
SCLogDebug("ID: %u seq: %u", ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p));
if (ICMPV6_GET_TYPE(p) != 128 || ICMPV6_GET_CODE(p) != 0 ||
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;
}
FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 128);
FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
FAIL_IF(SCNtohs(ICMPV6_GET_ID(p)) != 9712);
FAIL_IF(SCNtohs(ICMPV6_GET_SEQ(p)) != 29987);
PacketRecycle(p);
FlowShutdown();
@ -861,16 +870,10 @@ static int ICMPV6EchoRepTest01(void)
DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
FAIL_IF(!PacketIsICMPv6(p));
SCLogDebug("type: %u code %u ID: %u seq: %u", ICMPV6_GET_TYPE(p),
ICMPV6_GET_CODE(p),ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p));
if (ICMPV6_GET_TYPE(p) != 129 || ICMPV6_GET_CODE(p) != 0 ||
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;
}
FAIL_IF(ICMPV6_GET_TYPE(PacketGetICMPv6(p)) != 129);
FAIL_IF(ICMPV6_GET_CODE(PacketGetICMPv6(p)) != 0);
FAIL_IF(SCNtohs(ICMPV6_GET_ID(p)) != 9712);
FAIL_IF(SCNtohs(ICMPV6_GET_SEQ(p)) != 29987);
PacketRecycle(p);
FlowShutdown();
@ -911,7 +914,8 @@ static int ICMPV6ParamProbTest02(void)
FlowInitConfig(FLOW_QUIET);
DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
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));
PacketRecycle(p);
@ -1501,19 +1505,19 @@ static int ICMPV6CalculateValidChecksumWithFCS(void)
FAIL_IF_NULL(p);
ThreadVars tv;
DecodeThreadVars dtv;
memset(&tv, 0, sizeof(ThreadVars));
memset(&dtv, 0, sizeof(DecodeThreadVars));
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));
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
const IPV6Hdr *ip6h = PacketGetIPv6(p);
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(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);
FlowShutdown();

@ -98,32 +98,25 @@
/** 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 */
#define ICMPV6_GET_CODE(p) (p)->icmpv6h->code
/** macro for icmpv6 "csum" access */
#define ICMPV6_GET_RAW_CSUM(p) SCNtohs((p)->icmpv6h->csum)
#define ICMPV6_GET_CSUM(p) (p)->icmpv6h->csum
#define ICMPV6_GET_CODE(icmp6h) (icmp6h)->code
/** If message is informational */
/** 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 */
#define ICMPV6_GET_SEQ(p) (p)->icmpv6vars.seq
#define ICMPV6_GET_SEQ(p) (p)->l4.vars.icmpv6.seq
/** If message is Error */
/** macro for icmpv6 "unused" access */
#define ICMPV6_GET_UNUSED(p) (p)->icmpv6h->icmpv6b.icmpv6e.unused
/** macro for icmpv6 "mtu" accessibility */
// 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 */
#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 */
#define ICMPV6_GET_EMB_PROTO(p) (p)->icmpv6vars.emb_ip6_proto_next
/** macro for icmpv6 embedded "ipv6h" header access */
#define ICMPV6_GET_EMB_IPV6(p) (p)->icmpv6vars.emb_ipv6h
#define ICMPV6_GET_EMB_PROTO(p) (p)->l4.vars.icmpv6.emb_ip6_proto_next
typedef struct ICMPV6Info_
{
@ -167,12 +160,6 @@ typedef struct ICMPV6Vars_ {
IPV6Hdr *emb_ipv6h;
} ICMPV6Vars;
#define CLEAR_ICMPV6_PACKET(p) \
do { \
PACKET_CLEAR_L4VARS((p)); \
(p)->icmpv6h = NULL; \
} while (0)
void DecodeICMPV6RegisterTests(void);
int ICMPv6GetCounterpart(uint8_t type);

@ -428,6 +428,7 @@ struct PacketL3 {
enum PacketL4Types {
PACKET_L4_UNKNOWN = 0,
PACKET_L4_ICMPV6,
PACKET_L4_SCTP,
PACKET_L4_GRE,
PACKET_L4_ESP,
@ -438,10 +439,14 @@ struct PacketL4 {
bool csum_set;
uint16_t csum;
union L4Hdrs {
ICMPV6Hdr *icmpv6h;
SCTPHdr *sctph;
GREHdr *greh;
ESPHdr *esph;
} hdrs;
union L4Vars {
ICMPV6Vars icmpv6;
} vars;
};
/* sizes of the members:
@ -571,16 +576,13 @@ typedef struct Packet_
union {
TCPVars tcpvars;
ICMPV4Vars icmpv4vars;
ICMPV6Vars icmpv6vars;
} l4vars;
#define tcpvars l4vars.tcpvars
#define icmpv4vars l4vars.icmpv4vars
#define icmpv6vars l4vars.icmpv6vars
TCPHdr *tcph;
UDPHdr *udph;
ICMPV4Hdr *icmpv4h;
ICMPV6Hdr *icmpv6h;
PPPOESessionHdr *pppoesh;
PPPOEDiscoveryHdr *pppoedh;
@ -773,9 +775,23 @@ static inline bool PacketIsICMPv4(const Packet *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)
{
return PKT_IS_ICMPV6(p);
return p->l4.type == PACKET_L4_ICMPV6;
}
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;
if (!PacketIsIPv6(p) || !PacketIsICMPv6(p) || p->proto != IPPROTO_ICMPV6 ||
PKT_IS_PSEUDOPKT(p) ||
(GET_PKT_LEN(p) - ((uint8_t *)p->icmpv6h - GET_PKT_DATA(p))) <= 0) {
PKT_IS_PSEUDOPKT(p)) {
return 0;
}
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
if ((GET_PKT_LEN(p) - ((uint8_t *)icmpv6h - GET_PKT_DATA(p))) <= 0) {
return 0;
}
@ -788,14 +791,14 @@ static int DetectICMPV6CsumMatch(DetectEngineThreadCtx *det_ctx,
if (!p->l4.csum_set) {
const IPV6Hdr *ip6h = PacketGetIPv6(p);
uint16_t len = IPV6_GET_RAW_PLEN(ip6h) -
(uint16_t)((uint8_t *)p->icmpv6h - (uint8_t *)ip6h - IPV6_HEADER_LEN);
p->l4.csum = ICMPV6CalculateChecksum(ip6h->s_ip6_addrs, (uint16_t *)p->icmpv6h, len);
(uint16_t)((uint8_t *)icmpv6h - (uint8_t *)ip6h - IPV6_HEADER_LEN);
p->l4.csum = ICMPV6CalculateChecksum(ip6h->s_ip6_addrs, (uint16_t *)icmpv6h, len);
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;
else if (p->l4.csum != p->icmpv6h->csum && cd->valid == 0)
else if (p->l4.csum != icmpv6h->csum && cd->valid == 0)
return 1;
else
return 0;

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

@ -100,8 +100,7 @@ static inline bool GetIcmpSeq(Packet *p, uint16_t *seq)
return false;
}
} else if (PacketIsICMPv6(p)) {
switch (ICMPV6_GET_TYPE(p)) {
switch (ICMPV6_GET_TYPE(PacketGetICMPv6(p))) {
case ICMP6_ECHO_REQUEST:
case ICMP6_ECHO_REPLY:
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))
return 0;
if (ICMPV6_GET_CODE(p) != 0)
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
if (ICMPV6_GET_CODE(icmpv6h) != 0)
return 0;
if (!(ICMPV6_HAS_MTU(p)))
if (!(ICMPV6_HAS_MTU(icmpv6h)))
return 0;
*picmpv6mtu = ICMPV6_GET_MTU(p);
*picmpv6mtu = ICMPV6_GET_MTU(icmpv6h);
return 1;
}

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

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

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

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

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

@ -366,7 +366,7 @@ static void DPDKReleasePacket(Packet *p)
if ((p->dpdk_v.copy_mode == DPDK_COPY_MODE_TAP ||
(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)
&& !(PacketIsICMPv6(p) && p->icmpv6h->type == 143)
&& !(PacketIsICMPv6(p) && PacketGetICMPv6(p)->type == 143)
#endif
) {
BUG_ON(PKT_IS_PSEUDOPKT(p));

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

Loading…
Cancel
Save