From: Victor Julien Date: Sat, 30 Mar 2024 12:54:35 +0000 (+0100) Subject: decode/icmpv4: move icmpv4h into L4 packet data X-Git-Tag: suricata-8.0.0-beta1~1374 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=852ff83d70e1a806af55d989f31d98e7214468ab;p=thirdparty%2Fsuricata.git decode/icmpv4: move icmpv4h into L4 packet data To reduce Packet size. Ticket: #6938. --- diff --git a/src/decode-icmpv4.c b/src/decode-icmpv4.c index 2a1db22879..d167b97337 100644 --- a/src/decode-icmpv4.c +++ b/src/decode-icmpv4.c @@ -69,62 +69,62 @@ static int DecodePartialIPV4(Packet* p, uint8_t* partial_packet, uint16_t len) } /** We need to fill icmpv4vars */ - p->icmpv4vars.emb_ipv4h = icmp4_ip4h; + p->l4.vars.icmpv4.emb_ipv4h = icmp4_ip4h; switch (IPV4_GET_RAW_IPPROTO(icmp4_ip4h)) { case IPPROTO_TCP: if (len >= IPV4_HEADER_LEN + TCP_HEADER_LEN ) { TCPHdr *emb_tcph = (TCPHdr *)(partial_packet + IPV4_HEADER_LEN); - p->icmpv4vars.emb_sport = SCNtohs(emb_tcph->th_sport); - p->icmpv4vars.emb_dport = SCNtohs(emb_tcph->th_dport); - p->icmpv4vars.emb_ports_set = true; - p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP; + p->l4.vars.icmpv4.emb_sport = SCNtohs(emb_tcph->th_sport); + p->l4.vars.icmpv4.emb_dport = SCNtohs(emb_tcph->th_dport); + p->l4.vars.icmpv4.emb_ports_set = true; + p->l4.vars.icmpv4.emb_ip4_proto = IPPROTO_TCP; SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP header sport: " - "%"PRIu16" dport %"PRIu16"", p->icmpv4vars.emb_sport, - p->icmpv4vars.emb_dport); + "%" PRIu16 " dport %" PRIu16 "", + p->l4.vars.icmpv4.emb_sport, p->l4.vars.icmpv4.emb_dport); } else if (len >= IPV4_HEADER_LEN + 4) { /* only access th_sport and th_dport */ TCPHdr *emb_tcph = (TCPHdr *)(partial_packet + IPV4_HEADER_LEN); - p->icmpv4vars.emb_sport = SCNtohs(emb_tcph->th_sport); - p->icmpv4vars.emb_dport = SCNtohs(emb_tcph->th_dport); - p->icmpv4vars.emb_ports_set = true; - p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP; + p->l4.vars.icmpv4.emb_sport = SCNtohs(emb_tcph->th_sport); + p->l4.vars.icmpv4.emb_dport = SCNtohs(emb_tcph->th_dport); + p->l4.vars.icmpv4.emb_ports_set = true; + p->l4.vars.icmpv4.emb_ip4_proto = IPPROTO_TCP; SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP partial header sport: " - "%"PRIu16" dport %"PRIu16"", p->icmpv4vars.emb_sport, - p->icmpv4vars.emb_dport); + "%" PRIu16 " dport %" PRIu16 "", + p->l4.vars.icmpv4.emb_sport, p->l4.vars.icmpv4.emb_dport); } else { SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->TCP " "header Didn't fit in the packet!"); - p->icmpv4vars.emb_sport = 0; - p->icmpv4vars.emb_dport = 0; + p->l4.vars.icmpv4.emb_sport = 0; + p->l4.vars.icmpv4.emb_dport = 0; } break; case IPPROTO_UDP: if (len >= IPV4_HEADER_LEN + UDP_HEADER_LEN ) { UDPHdr *emb_udph = (UDPHdr *)(partial_packet + IPV4_HEADER_LEN); - p->icmpv4vars.emb_sport = SCNtohs(emb_udph->uh_sport); - p->icmpv4vars.emb_dport = SCNtohs(emb_udph->uh_dport); - p->icmpv4vars.emb_ports_set = true; - p->icmpv4vars.emb_ip4_proto = IPPROTO_UDP; + p->l4.vars.icmpv4.emb_sport = SCNtohs(emb_udph->uh_sport); + p->l4.vars.icmpv4.emb_dport = SCNtohs(emb_udph->uh_dport); + p->l4.vars.icmpv4.emb_ports_set = true; + p->l4.vars.icmpv4.emb_ip4_proto = IPPROTO_UDP; SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->UDP header sport: " - "%"PRIu16" dport %"PRIu16"", p->icmpv4vars.emb_sport, - p->icmpv4vars.emb_dport); + "%" PRIu16 " dport %" PRIu16 "", + p->l4.vars.icmpv4.emb_sport, p->l4.vars.icmpv4.emb_dport); } else { SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->UDP " "header Didn't fit in the packet!"); - p->icmpv4vars.emb_sport = 0; - p->icmpv4vars.emb_dport = 0; + p->l4.vars.icmpv4.emb_sport = 0; + p->l4.vars.icmpv4.emb_dport = 0; } break; case IPPROTO_ICMP: if (len >= IPV4_HEADER_LEN + ICMPV4_HEADER_LEN) { - p->icmpv4vars.emb_sport = 0; - p->icmpv4vars.emb_dport = 0; - p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP; + p->l4.vars.icmpv4.emb_sport = 0; + p->l4.vars.icmpv4.emb_dport = 0; + p->l4.vars.icmpv4.emb_ip4_proto = IPPROTO_ICMP; SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header"); } @@ -147,34 +147,33 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t return TM_ECODE_FAILED; } - p->icmpv4h = (ICMPV4Hdr *)pkt; + ICMPV4Hdr *icmpv4h = PacketSetICMPv4(p, pkt); - SCLogDebug("ICMPV4 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv4h->type, p->icmpv4h->code); + SCLogDebug("ICMPV4 TYPE %" PRIu32 " CODE %" PRIu32 "", icmpv4h->type, icmpv4h->code); p->proto = IPPROTO_ICMP; - p->icmp_s.type = p->icmpv4h->type; - p->icmp_s.code = p->icmpv4h->code; + const uint8_t type = p->icmp_s.type = icmpv4h->type; + const uint8_t code = p->icmp_s.code = icmpv4h->code; - int ctype = ICMPv4GetCounterpart(p->icmp_s.type); + int ctype = ICMPv4GetCounterpart(type); if (ctype != -1) { p->icmp_d.type = (uint8_t)ctype; } - ICMPV4ExtHdr* icmp4eh = (ICMPV4ExtHdr*) p->icmpv4h; - p->icmpv4vars.hlen = ICMPV4_HEADER_LEN; + ICMPV4ExtHdr *icmp4eh = (ICMPV4ExtHdr *)icmpv4h; + p->l4.vars.icmpv4.hlen = ICMPV4_HEADER_LEN; - switch (p->icmpv4h->type) - { + switch (type) { case ICMP_ECHOREPLY: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { + p->l4.vars.icmpv4.id = icmp4eh->id; + p->l4.vars.icmpv4.seq = icmp4eh->seq; + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } break; case ICMP_DEST_UNREACH: - if (p->icmpv4h->code > NR_ICMP_UNREACH) { + if (code > NR_ICMP_UNREACH) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } else { /* parse IP header plus 64 bytes */ @@ -189,7 +188,7 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t break; case ICMP_SOURCE_QUENCH: - if (p->icmpv4h->code!=0) { + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } else { // parse IP header plus 64 bytes @@ -204,7 +203,7 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t break; case ICMP_REDIRECT: - if (p->icmpv4h->code>ICMP_REDIR_HOSTTOS) { + if (code > ICMP_REDIR_HOSTTOS) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } else { // parse IP header plus 64 bytes @@ -219,15 +218,15 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t break; case ICMP_ECHO: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { + p->l4.vars.icmpv4.id = icmp4eh->id; + p->l4.vars.icmpv4.seq = icmp4eh->seq; + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } break; case ICMP_TIME_EXCEEDED: - if (p->icmpv4h->code>ICMP_EXC_FRAGTIME) { + if (code > ICMP_EXC_FRAGTIME) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } else { // parse IP header plus 64 bytes @@ -242,7 +241,7 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t break; case ICMP_PARAMETERPROB: - if (p->icmpv4h->code!=0) { + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } else { // parse IP header plus 64 bytes @@ -257,45 +256,45 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t break; case ICMP_TIMESTAMP: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { + p->l4.vars.icmpv4.id = icmp4eh->id; + p->l4.vars.icmpv4.seq = icmp4eh->seq; + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } if (len < (sizeof(ICMPV4Timestamp) + ICMPV4_HEADER_LEN)) { ENGINE_SET_EVENT(p, ICMPV4_IPV4_TRUNC_PKT); } else { - p->icmpv4vars.hlen += sizeof(ICMPV4Timestamp); + p->l4.vars.icmpv4.hlen += sizeof(ICMPV4Timestamp); } break; case ICMP_TIMESTAMPREPLY: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { + p->l4.vars.icmpv4.id = icmp4eh->id; + p->l4.vars.icmpv4.seq = icmp4eh->seq; + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } if (len < (sizeof(ICMPV4Timestamp) + ICMPV4_HEADER_LEN)) { ENGINE_SET_EVENT(p, ICMPV4_IPV4_TRUNC_PKT); } else { - p->icmpv4vars.hlen += sizeof(ICMPV4Timestamp); + p->l4.vars.icmpv4.hlen += sizeof(ICMPV4Timestamp); } break; case ICMP_INFO_REQUEST: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { + p->l4.vars.icmpv4.id = icmp4eh->id; + p->l4.vars.icmpv4.seq = icmp4eh->seq; + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } break; case ICMP_INFO_REPLY: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { + p->l4.vars.icmpv4.id = icmp4eh->id; + p->l4.vars.icmpv4.seq = icmp4eh->seq; + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } break; @@ -308,34 +307,33 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t if (len < (advert_len + ICMPV4_HEADER_LEN)) { ENGINE_SET_EVENT(p, ICMPV4_IPV4_TRUNC_PKT); } else { - p->icmpv4vars.hlen += advert_len; + p->l4.vars.icmpv4.hlen += advert_len; } } break; case ICMP_ADDRESS: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { + p->l4.vars.icmpv4.id = icmp4eh->id; + p->l4.vars.icmpv4.seq = icmp4eh->seq; + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } break; case ICMP_ADDRESSREPLY: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { + p->l4.vars.icmpv4.id = icmp4eh->id; + p->l4.vars.icmpv4.seq = icmp4eh->seq; + if (code != 0) { ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); } break; default: - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_TYPE); - + ENGINE_SET_EVENT(p, ICMPV4_UNKNOWN_TYPE); } - p->payload = (uint8_t *)pkt + p->icmpv4vars.hlen; - DEBUG_VALIDATE_BUG_ON(len - p->icmpv4vars.hlen > UINT16_MAX); - p->payload_len = (uint16_t)(len - p->icmpv4vars.hlen); + p->payload = (uint8_t *)pkt + p->l4.vars.icmpv4.hlen; + DEBUG_VALIDATE_BUG_ON(len - p->l4.vars.icmpv4.hlen > UINT16_MAX); + p->payload_len = (uint16_t)(len - p->l4.vars.icmpv4.hlen); FlowSetupPacket(p); return TM_ECODE_OK; @@ -374,11 +372,9 @@ static int DecodeICMPV4test01(void) 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab }; Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; + FAIL_IF_NULL(p); ThreadVars tv; DecodeThreadVars dtv; - int ret = 0; IPV4Hdr ip4h; memset(&ip4h, 0, sizeof(IPV4Hdr)); @@ -398,16 +394,17 @@ static int DecodeICMPV4test01(void) UTHSetIPV4Hdr(p, &ip4h); DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4)); + FAIL_IF_NOT(PacketIsICMPv4(p)); - if (NULL!=p->icmpv4h) { - if (p->icmpv4h->type==8 && p->icmpv4h->code==0) { - ret = 1; - } - } + const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p); + FAIL_IF_NULL(icmpv4h); + + FAIL_IF_NOT(icmpv4h->type == 8); + FAIL_IF_NOT(icmpv4h->code == 0); FlowShutdown(); SCFree(p); - return ret; + PASS; } /** DecodeICMPV4test02 @@ -425,11 +422,9 @@ static int DecodeICMPV4test02(void) 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f }; Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; + FAIL_IF_NULL(p); ThreadVars tv; DecodeThreadVars dtv; - int ret = 0; IPV4Hdr ip4h; memset(&ip4h, 0, sizeof(IPV4Hdr)); @@ -448,16 +443,17 @@ static int DecodeICMPV4test02(void) UTHSetIPV4Hdr(p, &ip4h); DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4)); + FAIL_IF_NOT(PacketIsICMPv4(p)); - if (NULL!=p->icmpv4h) { - if (p->icmpv4h->type==0 && p->icmpv4h->code==0) { - ret = 1; - } - } + const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p); + FAIL_IF_NULL(icmpv4h); + + FAIL_IF_NOT(icmpv4h->type == 0); + FAIL_IF_NOT(icmpv4h->code == 0); FlowShutdown(); SCFree(p); - return ret; + PASS; } /** DecodeICMPV4test03 @@ -473,11 +469,9 @@ static int DecodeICMPV4test03(void) 0xd1, 0x55, 0xe3, 0x93, 0x8b, 0x12, 0x82, 0xaa, 0x00, 0x28, 0x7c, 0xdd }; Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; + FAIL_IF_NULL(p); ThreadVars tv; DecodeThreadVars dtv; - int ret = 0; IPV4Hdr ip4h; memset(&ip4h, 0, sizeof(IPV4Hdr)); @@ -496,26 +490,18 @@ static int DecodeICMPV4test03(void) UTHSetIPV4Hdr(p, &ip4h); DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4)); + FAIL_IF_NOT(PacketIsICMPv4(p)); - if (NULL == p->icmpv4h) { - printf("NULL == p->icmpv4h: "); - goto end; - } + const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p); + FAIL_IF_NULL(icmpv4h); /* check it's type 11 code 0 */ - if (p->icmpv4h->type != 11 || p->icmpv4h->code != 0) { - printf("p->icmpv4h->type %u, p->icmpv4h->code %u: ", - p->icmpv4h->type, p->icmpv4h->code); - goto end; - } + FAIL_IF_NOT(icmpv4h->type == 11); + FAIL_IF_NOT(icmpv4h->code == 0); /* check it's source port 35602 to port 33450 */ - if (p->icmpv4vars.emb_sport != 35602 || - p->icmpv4vars.emb_dport != 33450) { - printf("p->icmpv4vars.emb_sport %u, p->icmpv4vars.emb_dport %u: ", - p->icmpv4vars.emb_sport, p->icmpv4vars.emb_dport); - goto end; - } + FAIL_IF(p->l4.vars.icmpv4.emb_sport != 35602); + FAIL_IF(p->l4.vars.icmpv4.emb_dport != 33450); /* check the src,dst IPs contained inside */ uint32_t src_ip = IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p)); @@ -525,17 +511,12 @@ static int DecodeICMPV4test03(void) PrintInet(AF_INET, &dst_ip, d, sizeof(d)); /* ICMPv4 embedding IPV4 192.168.1.13->209.85.227.147 pass */ - if (strcmp(s, "192.168.1.13") == 0 && strcmp(d, "209.85.227.147") == 0) { - ret = 1; - } - else { - printf("s %s, d %s: ", s, d); - } + FAIL_IF_NOT(strcmp(s, "192.168.1.13") == 0); + FAIL_IF_NOT(strcmp(d, "209.85.227.147") == 0); -end: FlowShutdown(); SCFree(p); - return ret; + PASS; } /** DecodeICMPV4test04 @@ -576,19 +557,17 @@ static int DecodeICMPV4test04(void) UTHSetIPV4Hdr(p, &ip4h); DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4)); + FAIL_IF_NOT(PacketIsICMPv4(p)); - if (NULL == p->icmpv4h) { - goto end; - } + const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p); + FAIL_IF_NULL(icmpv4h); /* check the type,code pair is correct - type 3, code 10 */ - if (p->icmpv4h->type != 3 || p->icmpv4h->code != 10) { - goto end; - } + FAIL_IF_NOT(icmpv4h->type == 3); + FAIL_IF_NOT(icmpv4h->code == 10); /* check it's src port 45322 to dst port 50 */ - if (p->icmpv4vars.emb_sport != 45322 || - p->icmpv4vars.emb_dport != 50) { + if (p->l4.vars.icmpv4.emb_sport != 45322 || p->l4.vars.icmpv4.emb_dport != 50) { goto end; } @@ -646,19 +625,17 @@ static int DecodeICMPV4test05(void) UTHSetIPV4Hdr(p, &ip4h); DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4)); + FAIL_IF_NOT(PacketIsICMPv4(p)); - if (NULL == p->icmpv4h) { - goto end; - } + const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p); + FAIL_IF_NULL(icmpv4h); /* check the type,code pair is correct - type 11, code 0 */ - if (p->icmpv4h->type != 11 || p->icmpv4h->code != 0) { - goto end; - } + FAIL_IF_NOT(icmpv4h->type == 11); + FAIL_IF_NOT(icmpv4h->code == 0); /* check it's src port 1048 to dst port 80 */ - if (p->icmpv4vars.emb_sport != 1048 || - p->icmpv4vars.emb_dport != 80) { + if (p->l4.vars.icmpv4.emb_sport != 1048 || p->l4.vars.icmpv4.emb_dport != 80) { goto end; } @@ -773,11 +750,9 @@ static int DecodeICMPV4test08(void) 0x08, 0x00, 0x78, 0x47, 0xfc, 0x55, 0x00, 0x00 }; Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; + FAIL_IF_NULL(p); ThreadVars tv; DecodeThreadVars dtv; - int ret = 0; IPV4Hdr ip4h; memset(&ip4h, 0, sizeof(IPV4Hdr)); @@ -796,16 +771,17 @@ static int DecodeICMPV4test08(void) UTHSetIPV4Hdr(p, &ip4h); DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4)); + FAIL_IF_NOT(PacketIsICMPv4(p)); - if (NULL!=p->icmpv4h) { - if (p->icmpv4h->type==8 && p->icmpv4h->code==0) { - ret = 1; - } - } + const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p); + FAIL_IF_NULL(icmpv4h); + + FAIL_IF_NOT(icmpv4h->type == 8); + FAIL_IF_NOT(icmpv4h->code == 0); FlowShutdown(); SCFree(p); - return ret; + PASS; } #endif /* UNITTESTS */ diff --git a/src/decode-icmpv4.h b/src/decode-icmpv4.h index 905b187b36..95f3c404e2 100644 --- a/src/decode-icmpv4.h +++ b/src/decode-icmpv4.h @@ -234,18 +234,18 @@ typedef struct ICMPV4Timestamp_ { /* If message is informational */ /** macro for icmpv4 "id" access */ -#define ICMPV4_GET_ID(p) ((p)->icmpv4vars.id) +#define ICMPV4_GET_ID(p) ((p)->l4.vars.icmpv4.id) /** macro for icmpv4 "seq" access */ -#define ICMPV4_GET_SEQ(p) ((p)->icmpv4vars.seq) +#define ICMPV4_GET_SEQ(p) ((p)->l4.vars.icmpv4.seq) /* If message is Error */ /** macro for icmpv4 embedded "protocol" access */ -#define ICMPV4_GET_EMB_PROTO(p) (p)->icmpv4vars.emb_ip4_proto +#define ICMPV4_GET_EMB_PROTO(p) (p)->l4.vars.icmpv4.emb_ip4_proto /** macro for icmpv4 embedded "ipv4h" header access */ -#define ICMPV4_GET_EMB_IPV4(p) (p)->icmpv4vars.emb_ipv4h +#define ICMPV4_GET_EMB_IPV4(p) (p)->l4.vars.icmpv4.emb_ipv4h /** macro for icmpv4 header length */ -#define ICMPV4_GET_HLEN_ICMPV4H(p) (p)->icmpv4vars.hlen +#define ICMPV4_GET_HLEN_ICMPV4H(p) (p)->l4.vars.icmpv4.hlen /** macro for checking if a ICMP DEST UNREACH packet is valid for use * in other parts of the engine, such as the flow engine. @@ -253,9 +253,9 @@ typedef struct ICMPV4Timestamp_ { * \warning use only _after_ the decoder has processed the packet */ #define ICMPV4_DEST_UNREACH_IS_VALID(p) \ - ((!((p)->flags & PKT_IS_INVALID)) && ((p)->icmpv4h != NULL) && \ - (ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH) && (ICMPV4_GET_EMB_IPV4((p)) != NULL) && \ - (p)->icmpv4vars.emb_ports_set) + ((!((p)->flags & PKT_IS_INVALID)) && PacketIsICMPv4((p)) && \ + ((p)->icmp_s.type == ICMP_DEST_UNREACH) && (ICMPV4_GET_EMB_IPV4((p)) != NULL) && \ + (p)->l4.vars.icmpv4.emb_ports_set) /** * marco for checking if a ICMP packet is an error message or an @@ -266,11 +266,9 @@ typedef struct ICMPV4Timestamp_ { * stage so we can to a bit check instead of the more expensive * check below. */ -#define ICMPV4_IS_ERROR_MSG(p) (ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH || \ - ICMPV4_GET_TYPE((p)) == ICMP_SOURCE_QUENCH || \ - ICMPV4_GET_TYPE((p)) == ICMP_REDIRECT || \ - ICMPV4_GET_TYPE((p)) == ICMP_TIME_EXCEEDED || \ - ICMPV4_GET_TYPE((p)) == ICMP_PARAMETERPROB) +#define ICMPV4_IS_ERROR_MSG(type) \ + ((type) == ICMP_DEST_UNREACH || (type) == ICMP_SOURCE_QUENCH || (type) == ICMP_REDIRECT || \ + (type) == ICMP_TIME_EXCEEDED || (type) == ICMP_PARAMETERPROB) void DecodeICMPV4RegisterTests(void); diff --git a/src/decode.h b/src/decode.h index 310ab46251..86e7d6faf5 100644 --- a/src/decode.h +++ b/src/decode.h @@ -428,6 +428,7 @@ struct PacketL3 { enum PacketL4Types { PACKET_L4_UNKNOWN = 0, + PACKET_L4_ICMPV4, PACKET_L4_ICMPV6, PACKET_L4_SCTP, PACKET_L4_GRE, @@ -439,12 +440,14 @@ struct PacketL4 { bool csum_set; uint16_t csum; union L4Hdrs { + ICMPV4Hdr *icmpv4h; ICMPV6Hdr *icmpv6h; SCTPHdr *sctph; GREHdr *greh; ESPHdr *esph; } hdrs; union L4Vars { + ICMPV4Vars icmpv4; ICMPV6Vars icmpv6; } vars; }; @@ -575,14 +578,11 @@ typedef struct Packet_ /* Can only be one of TCP, UDP, ICMP at any given time */ union { TCPVars tcpvars; - ICMPV4Vars icmpv4vars; } l4vars; -#define tcpvars l4vars.tcpvars -#define icmpv4vars l4vars.icmpv4vars +#define tcpvars l4vars.tcpvars TCPHdr *tcph; UDPHdr *udph; - ICMPV4Hdr *icmpv4h; PPPOESessionHdr *pppoesh; PPPOEDiscoveryHdr *pppoedh; @@ -770,9 +770,23 @@ static inline bool PacketIsUDP(const Packet *p) return PKT_IS_UDP(p); } +static inline ICMPV4Hdr *PacketSetICMPv4(Packet *p, const uint8_t *buf) +{ + DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_UNKNOWN); + p->l4.type = PACKET_L4_ICMPV4; + p->l4.hdrs.icmpv4h = (ICMPV4Hdr *)buf; + return p->l4.hdrs.icmpv4h; +} + +static inline const ICMPV4Hdr *PacketGetICMPv4(const Packet *p) +{ + DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_ICMPV4); + return p->l4.hdrs.icmpv4h; +} + static inline bool PacketIsICMPv4(const Packet *p) { - return PKT_IS_ICMPV4(p); + return p->l4.type == PACKET_L4_ICMPV4; } static inline ICMPV6Hdr *PacketSetICMPv6(Packet *p, const uint8_t *buf) diff --git a/src/detect-csum.c b/src/detect-csum.c index 1bdb7003b4..65da52e978 100644 --- a/src/detect-csum.c +++ b/src/detect-csum.c @@ -693,15 +693,16 @@ static int DetectICMPV4CsumMatch(DetectEngineThreadCtx *det_ctx, return cd->valid; } + const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p); if (!p->l4.csum_set) { const IPV4Hdr *ip4h = PacketGetIPv4(p); p->l4.csum = ICMPV4CalculateChecksum( - (uint16_t *)p->icmpv4h, IPV4_GET_RAW_IPLEN(ip4h) - IPV4_GET_RAW_HLEN(ip4h)); + (uint16_t *)icmpv4h, IPV4_GET_RAW_IPLEN(ip4h) - IPV4_GET_RAW_HLEN(ip4h)); p->l4.csum_set = true; } - if (p->l4.csum == p->icmpv4h->checksum && cd->valid == 1) + if (p->l4.csum == icmpv4h->checksum && cd->valid == 1) return 1; - else if (p->l4.csum != p->icmpv4h->checksum && cd->valid == 0) + else if (p->l4.csum != icmpv4h->checksum && cd->valid == 0) return 1; else return 0; diff --git a/src/detect-engine-siggroup.c b/src/detect-engine-siggroup.c index 7979c0a9da..e483c918b4 100644 --- a/src/detect-engine-siggroup.c +++ b/src/detect-engine-siggroup.c @@ -1051,9 +1051,10 @@ static int SigGroupHeadTest06(void) Packet *p = UTHBuildPacketSrcDst(NULL, 0, IPPROTO_ICMP, "192.168.1.1", "1.2.3.4"); FAIL_IF_NULL(p); + FAIL_IF_NOT(PacketIsICMPv4(p)); - p->icmpv4h->type = 5; - p->icmpv4h->code = 1; + p->l4.hdrs.icmpv4h->type = 5; + p->l4.hdrs.icmpv4h->code = 1; /* originally ip's were p.src.addr_data32[0] = 0xe08102d3; diff --git a/src/detect-icmp-id.c b/src/detect-icmp-id.c index a803bab294..b35839a765 100644 --- a/src/detect-icmp-id.c +++ b/src/detect-icmp-id.c @@ -80,7 +80,7 @@ static inline bool GetIcmpId(Packet *p, uint16_t *id) uint16_t pid; if (PacketIsICMPv4(p)) { - switch (ICMPV4_GET_TYPE(p)){ + switch (p->icmp_s.type) { case ICMP_ECHOREPLY: case ICMP_ECHO: case ICMP_TIMESTAMP: @@ -407,7 +407,7 @@ static int DetectIcmpIdMatchTest01 (void) memset(&th_v, 0, sizeof(ThreadVars)); p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); - p->icmpv4vars.id = htons(21781); + p->l4.vars.icmpv4.id = htons(21781); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { diff --git a/src/detect-icmp-seq.c b/src/detect-icmp-seq.c index 5b769e1f36..ad8206a2f6 100644 --- a/src/detect-icmp-seq.c +++ b/src/detect-icmp-seq.c @@ -80,7 +80,7 @@ static inline bool GetIcmpSeq(Packet *p, uint16_t *seq) return false; if (PacketIsICMPv4(p)) { - switch (ICMPV4_GET_TYPE(p)){ + switch (p->icmp_s.type) { case ICMP_ECHOREPLY: case ICMP_ECHO: case ICMP_TIMESTAMP: diff --git a/src/detect-icmpv4hdr.c b/src/detect-icmpv4hdr.c index fe029ec9fa..0d4e90675c 100644 --- a/src/detect-icmpv4hdr.c +++ b/src/detect-icmpv4hdr.c @@ -101,16 +101,17 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { + const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p); uint16_t hlen = ICMPV4_GET_HLEN_ICMPV4H(p); - if (((uint8_t *)p->icmpv4h + (ptrdiff_t)hlen) > + if (((uint8_t *)icmpv4h + (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->icmpv4h + (ptrdiff_t)hlen), + SCLogDebug("data out of range: %p > %p", ((uint8_t *)icmpv4h + (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->icmpv4h; + const uint8_t *data = (const uint8_t *)icmpv4h; InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferApplyTransforms(buffer, transforms); diff --git a/src/detect-icode.c b/src/detect-icode.c index e53ac790bd..33d5beea4e 100644 --- a/src/detect-icode.c +++ b/src/detect-icode.c @@ -92,7 +92,7 @@ static int DetectICodeMatch (DetectEngineThreadCtx *det_ctx, Packet *p, uint8_t picode; if (PacketIsICMPv4(p)) { - picode = ICMPV4_GET_CODE(p); + picode = p->icmp_s.code; } else if (PacketIsICMPv6(p)) { const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p); picode = ICMPV6_GET_CODE(icmpv6h); @@ -158,7 +158,7 @@ static void PrefilterPacketICodeMatch(DetectEngineThreadCtx *det_ctx, uint8_t picode; if (PacketIsICMPv4(p)) { - picode = ICMPV4_GET_CODE(p); + picode = p->icmp_s.code; } else if (PacketIsICMPv6(p)) { const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p); picode = ICMPV6_GET_CODE(icmpv6h); @@ -335,17 +335,16 @@ static int DetectICodeParseTest09(void) */ static int DetectICodeMatchTest01(void) { - - Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); - - p->icmpv4h->code = 10; + Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); + FAIL_IF_NULL(p); + FAIL_IF_NOT(PacketIsICMPv4(p)); + p->icmp_s.code = p->l4.hdrs.icmpv4h->code = 10; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); FAIL_IF_NULL(de_ctx); diff --git a/src/detect-itype.c b/src/detect-itype.c index 94856a0b4c..8a9af90883 100644 --- a/src/detect-itype.c +++ b/src/detect-itype.c @@ -89,7 +89,7 @@ static int DetectITypeMatch (DetectEngineThreadCtx *det_ctx, Packet *p, uint8_t pitype; if (PacketIsICMPv4(p)) { - pitype = ICMPV4_GET_TYPE(p); + pitype = p->icmp_s.type; } else if (PacketIsICMPv6(p)) { const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p); pitype = ICMPV6_GET_TYPE(icmpv6h); @@ -174,7 +174,7 @@ static void PrefilterPacketITypeMatch(DetectEngineThreadCtx *det_ctx, uint8_t pitype; if (PacketIsICMPv4(p)) { - pitype = ICMPV4_GET_TYPE(p); + pitype = p->icmp_s.type; } else if (PacketIsICMPv6(p)) { const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p); pitype = ICMPV6_GET_TYPE(icmpv6h); diff --git a/src/flow-hash.c b/src/flow-hash.c index 0235513d97..409b00f654 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -226,9 +226,9 @@ static inline uint32_t FlowGetHash(const Packet *p) fhk.addrs[1-ai] = psrc; fhk.addrs[ai] = pdst; - const int pi = (p->icmpv4vars.emb_sport > p->icmpv4vars.emb_dport); - fhk.ports[1-pi] = p->icmpv4vars.emb_sport; - fhk.ports[pi] = p->icmpv4vars.emb_dport; + const int pi = (p->l4.vars.icmpv4.emb_sport > p->l4.vars.icmpv4.emb_dport); + fhk.ports[1 - pi] = p->l4.vars.icmpv4.emb_sport; + fhk.ports[pi] = p->l4.vars.icmpv4.emb_dport; fhk.proto = ICMPV4_GET_EMB_PROTO(p); fhk.recur = p->recursion_level; @@ -470,7 +470,7 @@ static inline int FlowCompareICMPv4(Flow *f, const Packet *p) * response to the clients traffic */ if ((f->src.addr_data32[0] == IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p))) && (f->dst.addr_data32[0] == IPV4_GET_RAW_IPDST_U32(ICMPV4_GET_EMB_IPV4(p))) && - f->sp == p->icmpv4vars.emb_sport && f->dp == p->icmpv4vars.emb_dport && + f->sp == p->l4.vars.icmpv4.emb_sport && f->dp == p->l4.vars.icmpv4.emb_dport && f->proto == ICMPV4_GET_EMB_PROTO(p) && f->recursion_level == p->recursion_level && CmpVlanIds(f->vlan_id, p->vlan_id) && (f->livedev == p->livedev || g_livedev_mask == 0)) { @@ -480,7 +480,7 @@ static inline int FlowCompareICMPv4(Flow *f, const Packet *p) * a packet from the server. */ } else if ((f->dst.addr_data32[0] == IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p))) && (f->src.addr_data32[0] == IPV4_GET_RAW_IPDST_U32(ICMPV4_GET_EMB_IPV4(p))) && - f->dp == p->icmpv4vars.emb_sport && f->sp == p->icmpv4vars.emb_dport && + f->dp == p->l4.vars.icmpv4.emb_sport && f->sp == p->l4.vars.icmpv4.emb_dport && f->proto == ICMPV4_GET_EMB_PROTO(p) && f->recursion_level == p->recursion_level && CmpVlanIds(f->vlan_id, p->vlan_id) && (f->livedev == p->livedev || g_livedev_mask == 0)) { @@ -562,7 +562,7 @@ static inline int FlowCreateCheck(const Packet *p, const bool emerg) } if (PacketIsICMPv4(p)) { - if (ICMPV4_IS_ERROR_MSG(p)) { + if (ICMPV4_IS_ERROR_MSG(p->icmp_s.type)) { return 0; } } diff --git a/src/flow.c b/src/flow.c index f11b024eb1..5f23ac8f51 100644 --- a/src/flow.c +++ b/src/flow.c @@ -329,7 +329,7 @@ int FlowGetPacketDirection(const Flow *f, const Packet *p) static inline int FlowUpdateSeenFlag(const Packet *p) { if (PacketIsICMPv4(p)) { - if (ICMPV4_IS_ERROR_MSG(p)) { + if (ICMPV4_IS_ERROR_MSG(p->icmp_s.type)) { return 0; } } diff --git a/src/output-json.c b/src/output-json.c index 31802b0181..8ab78150be 100644 --- a/src/output-json.c +++ b/src/output-json.c @@ -839,9 +839,9 @@ JsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir, /* icmp */ switch (p->proto) { case IPPROTO_ICMP: - if (p->icmpv4h) { - jb_set_uint(js, "icmp_type", p->icmpv4h->type); - jb_set_uint(js, "icmp_code", p->icmpv4h->code); + if (PacketIsICMPv4(p)) { + jb_set_uint(js, "icmp_type", p->icmp_s.type); + jb_set_uint(js, "icmp_code", p->icmp_s.code); } break; case IPPROTO_ICMPV6: diff --git a/src/packet.c b/src/packet.c index ed268fb1dc..73c38206db 100644 --- a/src/packet.c +++ b/src/packet.c @@ -121,9 +121,6 @@ void PacketReinit(Packet *p) if (p->udph != NULL) { CLEAR_UDP_PACKET(p); } - if (p->icmpv4h != NULL) { - CLEAR_ICMPV4_PACKET(p); - } p->pppoesh = NULL; p->pppoedh = NULL; p->payload = NULL; diff --git a/src/tests/detect.c b/src/tests/detect.c index 4efd32194c..7a150d4a57 100644 --- a/src/tests/detect.c +++ b/src/tests/detect.c @@ -2825,7 +2825,7 @@ static int SigTest34ICMPV4Keyword(void) IPV4Hdr *ip4h = PacketSetIPV4(p1, valid_raw_ipv4); ip4h->ip_verhl = 69; - p1->icmpv4h = (ICMPV4Hdr *)(valid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h)); + (void)PacketSetICMPv4(p1, valid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h)); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = buf; @@ -2834,7 +2834,7 @@ static int SigTest34ICMPV4Keyword(void) ip4h = PacketSetIPV4(p2, invalid_raw_ipv4); ip4h->ip_verhl = 69; - p2->icmpv4h = (ICMPV4Hdr *)(invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h)); + (void)PacketSetICMPv4(p2, invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h)); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = buf; @@ -2941,7 +2941,7 @@ static int SigTest35NegativeICMPV4Keyword(void) IPV4Hdr *ip4h = PacketSetIPV4(p1, valid_raw_ipv4); ip4h->ip_verhl = 69; - p1->icmpv4h = (ICMPV4Hdr *)(valid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h)); + (void)PacketSetICMPv4(p1, valid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h)); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = buf; @@ -2950,7 +2950,7 @@ static int SigTest35NegativeICMPV4Keyword(void) ip4h = PacketSetIPV4(p2, invalid_raw_ipv4); ip4h->ip_verhl = 69; - p2->icmpv4h = (ICMPV4Hdr *)(invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h)); + (void)PacketSetICMPv4(p2, invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h)); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = buf; diff --git a/src/util-unittest-helper.c b/src/util-unittest-helper.c index a79e614873..10ad38f929 100644 --- a/src/util-unittest-helper.c +++ b/src/util-unittest-helper.c @@ -310,13 +310,14 @@ Packet *UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, p->tcph->th_dport = htons(dport); hdr_offset += sizeof(TCPHdr); break; - case IPPROTO_ICMP: - p->icmpv4h = (ICMPV4Hdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); - if (p->icmpv4h == NULL) + case IPPROTO_ICMP: { + ICMPV4Hdr *icmpv4h = PacketSetICMPv4(p, (GET_PKT_DATA(p) + sizeof(IPV4Hdr))); + if (icmpv4h == NULL) goto error; hdr_offset += sizeof(ICMPV4Hdr); break; + } default: break; /* TODO: Add more protocols */ diff --git a/src/util-validate.h b/src/util-validate.h index 21b5785f1e..4f4a46ec9e 100644 --- a/src/util-validate.h +++ b/src/util-validate.h @@ -77,7 +77,7 @@ } else if ((p)->proto == IPPROTO_UDP) { \ BUG_ON((p)->udph == NULL); \ } else if ((p)->proto == IPPROTO_ICMP) { \ - BUG_ON((p)->icmpv4h == NULL); \ + BUG_ON(PacketGetICMPv4((p)) == NULL); \ } else if ((p)->proto == IPPROTO_SCTP) { \ BUG_ON(PacketGetSCTP((p)) == NULL); \ } else if ((p)->proto == IPPROTO_ICMPV6) { \