From: Victor Julien Date: Tue, 2 Apr 2024 15:47:10 +0000 (+0200) Subject: decode/udp: move udph into L4 packet data X-Git-Tag: suricata-8.0.0-beta1~1370 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=28ac86096ab520978a716fc917d36e85e44e8034;p=thirdparty%2Fsuricata.git decode/udp: move udph into L4 packet data To recude Packet size. Ticket: #6938. --- diff --git a/src/decode-udp.c b/src/decode-udp.c index 1ecaf54f6f..6d34250d22 100644 --- a/src/decode-udp.c +++ b/src/decode-udp.c @@ -49,23 +49,23 @@ static int DecodeUDPPacket(ThreadVars *t, Packet *p, const uint8_t *pkt, uint16_ return -1; } - p->udph = (UDPHdr *)pkt; + const UDPHdr *udph = PacketSetUDP(p, pkt); - if (unlikely(len < UDP_GET_LEN(p))) { + if (unlikely(len < UDP_GET_RAW_LEN(udph))) { ENGINE_SET_INVALID_EVENT(p, UDP_PKT_TOO_SMALL); return -1; } - if (unlikely(UDP_GET_LEN(p) < UDP_HEADER_LEN)) { + if (unlikely(UDP_GET_RAW_LEN(udph) < UDP_HEADER_LEN)) { ENGINE_SET_INVALID_EVENT(p, UDP_LEN_INVALID); return -1; } - SET_UDP_SRC_PORT(p,&p->sp); - SET_UDP_DST_PORT(p,&p->dp); + p->sp = UDP_GET_RAW_SRC_PORT(udph); + p->dp = UDP_GET_RAW_DST_PORT(udph); p->payload = (uint8_t *)pkt + UDP_HEADER_LEN; - p->payload_len = UDP_GET_LEN(p) - UDP_HEADER_LEN; + p->payload_len = UDP_GET_RAW_LEN(udph) - UDP_HEADER_LEN; p->proto = IPPROTO_UDP; @@ -78,12 +78,12 @@ int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, StatsIncr(tv, dtv->counter_udp); if (unlikely(DecodeUDPPacket(tv, p, pkt,len) < 0)) { - CLEAR_UDP_PACKET(p); + PacketClearL4(p); return TM_ECODE_FAILED; } - SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "", - UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_HEADER_LEN, p->payload_len); + SCLogDebug("UDP sp: %u -> dp: %u - HLEN: %" PRIu32 " LEN: %" PRIu32 "", p->sp, p->dp, + UDP_HEADER_LEN, p->payload_len); if (DecodeTeredoEnabledForPort(p->sp, p->dp) && likely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len) == TM_ECODE_OK)) { diff --git a/src/decode-udp.h b/src/decode-udp.h index 24249508a7..b6a5537bb4 100644 --- a/src/decode-udp.h +++ b/src/decode-udp.h @@ -46,11 +46,6 @@ typedef struct UDPHdr_ uint16_t uh_sum; /* checksum */ } UDPHdr; -#define CLEAR_UDP_PACKET(p) \ - do { \ - (p)->udph = NULL; \ - } while (0) - void DecodeUDPV4RegisterTests(void); /** ------ Inline function ------ */ diff --git a/src/decode.h b/src/decode.h index 6569341544..0afd818364 100644 --- a/src/decode.h +++ b/src/decode.h @@ -439,6 +439,7 @@ struct PacketL3 { enum PacketL4Types { PACKET_L4_UNKNOWN = 0, + PACKET_L4_UDP, PACKET_L4_ICMPV4, PACKET_L4_ICMPV6, PACKET_L4_SCTP, @@ -451,6 +452,7 @@ struct PacketL4 { bool csum_set; uint16_t csum; union L4Hdrs { + UDPHdr *udph; ICMPV4Hdr *icmpv4h; ICMPV6Hdr *icmpv6h; SCTPHdr *sctph; @@ -591,7 +593,6 @@ typedef struct Packet_ #define tcpvars l4vars.tcpvars TCPHdr *tcph; - UDPHdr *udph; /* ptr to the payload of the packet * with it's length. */ @@ -797,9 +798,23 @@ static inline bool PacketIsTCP(const Packet *p) return PKT_IS_TCP(p); } +static inline UDPHdr *PacketSetUDP(Packet *p, const uint8_t *buf) +{ + DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_UNKNOWN); + p->l4.type = PACKET_L4_UDP; + p->l4.hdrs.udph = (UDPHdr *)buf; + return p->l4.hdrs.udph; +} + +static inline const UDPHdr *PacketGetUDP(const Packet *p) +{ + DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_UDP); + return p->l4.hdrs.udph; +} + static inline bool PacketIsUDP(const Packet *p) { - return PKT_IS_UDP(p); + return p->l4.type == PACKET_L4_UDP; } static inline ICMPV4Hdr *PacketSetICMPv4(Packet *p, const uint8_t *buf) diff --git a/src/detect-csum.c b/src/detect-csum.c index 65da52e978..a43fbf1cff 100644 --- a/src/detect-csum.c +++ b/src/detect-csum.c @@ -507,8 +507,11 @@ static int DetectUDPV4CsumMatch(DetectEngineThreadCtx *det_ctx, { const DetectCsumData *cd = (const DetectCsumData *)ctx; - if (!PacketIsIPv4(p) || !PacketIsUDP(p) || p->proto != IPPROTO_UDP || PKT_IS_PSEUDOPKT(p) || - p->udph->uh_sum == 0) + if (!PacketIsIPv4(p) || !PacketIsUDP(p) || p->proto != IPPROTO_UDP || PKT_IS_PSEUDOPKT(p)) + return 0; + + const UDPHdr *udph = PacketGetUDP(p); + if (udph->uh_sum == 0) return 0; if (p->flags & PKT_IGNORE_CHECKSUM) { @@ -517,8 +520,8 @@ static int DetectUDPV4CsumMatch(DetectEngineThreadCtx *det_ctx, if (!p->l4.csum_set) { const IPV4Hdr *ip4h = PacketGetIPv4(p); - p->l4.csum = UDPV4Checksum(ip4h->s_ip_addrs, (uint16_t *)p->udph, - (p->payload_len + UDP_HEADER_LEN), p->udph->uh_sum); + p->l4.csum = UDPV4Checksum(ip4h->s_ip_addrs, (uint16_t *)udph, + (p->payload_len + UDP_HEADER_LEN), udph->uh_sum); p->l4.csum_set = true; } if (p->l4.csum == 0 && cd->valid == 1) @@ -606,8 +609,9 @@ static int DetectUDPV6CsumMatch(DetectEngineThreadCtx *det_ctx, if (!p->l4.csum_set) { const IPV6Hdr *ip6h = PacketGetIPv6(p); - p->l4.csum = UDPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->udph, - (p->payload_len + UDP_HEADER_LEN), p->udph->uh_sum); + const UDPHdr *udph = PacketGetUDP(p); + p->l4.csum = UDPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)udph, + (p->payload_len + UDP_HEADER_LEN), udph->uh_sum); p->l4.csum_set = true; } if (p->l4.csum == 0 && cd->valid == 1) diff --git a/src/detect-udphdr.c b/src/detect-udphdr.c index 79d43b7632..cfc91bc7a1 100644 --- a/src/detect-udphdr.c +++ b/src/detect-udphdr.c @@ -102,17 +102,16 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, if (!PacketIsUDP(p)) { return NULL; } - if (((uint8_t *)p->udph + (ptrdiff_t)UDP_HEADER_LEN) > - ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) - { - SCLogDebug("data out of range: %p > %p", - ((uint8_t *)p->udph + (ptrdiff_t)UDP_HEADER_LEN), + const UDPHdr *udph = PacketGetUDP(p); + if (((uint8_t *)udph + (ptrdiff_t)UDP_HEADER_LEN) > + ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) { + SCLogDebug("data out of range: %p > %p", ((uint8_t *)udph + (ptrdiff_t)UDP_HEADER_LEN), ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))); return NULL; } const uint32_t data_len = UDP_HEADER_LEN; - const uint8_t *data = (const uint8_t *)p->udph; + const uint8_t *data = (const uint8_t *)udph; InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferApplyTransforms(buffer, transforms); diff --git a/src/flow-util.c b/src/flow-util.c index 10159a2598..d4cded6f58 100644 --- a/src/flow-util.c +++ b/src/flow-util.c @@ -174,8 +174,8 @@ void FlowInit(Flow *f, const Packet *p) SET_TCP_SRC_PORT(p,&f->sp); SET_TCP_DST_PORT(p,&f->dp); } else if (PacketIsUDP(p)) { - SET_UDP_SRC_PORT(p,&f->sp); - SET_UDP_DST_PORT(p,&f->dp); + f->sp = p->sp; + f->dp = p->dp; } else if (PacketIsICMPv4(p)) { f->icmp_s.type = p->icmp_s.type; f->icmp_s.code = p->icmp_s.code; diff --git a/src/output-json-drop.c b/src/output-json-drop.c index a56856d4f0..03869e0bec 100644 --- a/src/output-json-drop.c +++ b/src/output-json-drop.c @@ -140,7 +140,8 @@ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p) break; case IPPROTO_UDP: if (PacketIsUDP(p)) { - jb_set_uint(js, "udplen", UDP_GET_LEN(p)); + const UDPHdr *udph = PacketGetUDP(p); + jb_set_uint(js, "udplen", UDP_GET_RAW_LEN(udph)); } break; case IPPROTO_ICMP: diff --git a/src/packet.c b/src/packet.c index de04aa59a8..e0c3327c44 100644 --- a/src/packet.c +++ b/src/packet.c @@ -118,9 +118,6 @@ void PacketReinit(Packet *p) if (p->tcph != NULL) { CLEAR_TCP_PACKET(p); } - if (p->udph != NULL) { - CLEAR_UDP_PACKET(p); - } p->payload = NULL; p->payload_len = 0; p->BypassPacketsFlow = NULL; diff --git a/src/tests/detect.c b/src/tests/detect.c index 5919e44bc7..2476ac0966 100644 --- a/src/tests/detect.c +++ b/src/tests/detect.c @@ -2400,7 +2400,7 @@ static int SigTest30UDPV4Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PacketSetIPV4(p1, raw_ipv4); - p1->udph = (UDPHdr *)valid_raw_udp; + PacketSetUDP(p1, valid_raw_udp); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = buf; @@ -2408,7 +2408,7 @@ static int SigTest30UDPV4Keyword(void) p1->proto = IPPROTO_UDP; PacketSetIPV4(p2, raw_ipv4); - p2->udph = (UDPHdr *)invalid_raw_udp; + PacketSetUDP(p2, invalid_raw_udp); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = buf; @@ -2504,7 +2504,7 @@ static int SigTest31NegativeUDPV4Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PacketSetIPV4(p1, raw_ipv4); - p1->udph = (UDPHdr *)valid_raw_udp; + PacketSetUDP(p1, valid_raw_udp); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = buf; @@ -2512,7 +2512,7 @@ static int SigTest31NegativeUDPV4Keyword(void) p1->proto = IPPROTO_UDP; PacketSetIPV4(p2, raw_ipv4); - p2->udph = (UDPHdr *)invalid_raw_udp; + PacketSetUDP(p2, invalid_raw_udp); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = buf; @@ -2613,7 +2613,7 @@ static int SigTest32UDPV6Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PacketSetIPV6(p1, valid_raw_ipv6 + 14); - p1->udph = (UDPHdr *) (valid_raw_ipv6 + 54); + PacketSetUDP(p1, valid_raw_ipv6 + 54); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = buf; @@ -2621,7 +2621,7 @@ static int SigTest32UDPV6Keyword(void) p1->proto = IPPROTO_UDP; PacketSetIPV6(p2, invalid_raw_ipv6 + 14); - p2->udph = (UDPHdr *) (invalid_raw_ipv6 + 54); + PacketSetUDP(p2, invalid_raw_ipv6 + 54); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = buf; @@ -2710,7 +2710,7 @@ static int SigTest33NegativeUDPV6Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PacketSetIPV6(p1, valid_raw_ipv6 + 14); - p1->udph = (UDPHdr *) (valid_raw_ipv6 + 54); + PacketSetUDP(p1, valid_raw_ipv6 + 54); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = buf; @@ -2718,7 +2718,7 @@ static int SigTest33NegativeUDPV6Keyword(void) p1->proto = IPPROTO_UDP; PacketSetIPV6(p2, invalid_raw_ipv6 + 14); - p2->udph = (UDPHdr *) (invalid_raw_ipv6 + 54); + PacketSetUDP(p2, invalid_raw_ipv6 + 54); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = buf; diff --git a/src/util-checksum.c b/src/util-checksum.c index 4f19c6dae2..33cddbb5a5 100644 --- a/src/util-checksum.c +++ b/src/util-checksum.c @@ -36,9 +36,9 @@ int ReCalculateChecksum(Packet *p) p->tcph->th_sum = TCPChecksum( ip4h->s_ip_addrs, (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); } else if (PacketIsUDP(p)) { - p->udph->uh_sum = 0; - p->udph->uh_sum = UDPV4Checksum( - ip4h->s_ip_addrs, (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0); + p->l4.hdrs.udph->uh_sum = 0; + p->l4.hdrs.udph->uh_sum = UDPV4Checksum(ip4h->s_ip_addrs, (uint16_t *)p->l4.hdrs.udph, + (p->payload_len + UDP_HEADER_LEN), 0); } /* IPV4 */ ip4h->ip_csum = 0; @@ -50,9 +50,9 @@ int ReCalculateChecksum(Packet *p) p->tcph->th_sum = TCPV6Checksum( ip6h->s_ip6_addrs, (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); } else if (PacketIsUDP(p)) { - p->udph->uh_sum = 0; - p->udph->uh_sum = UDPV6Checksum( - ip6h->s_ip6_addrs, (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0); + p->l4.hdrs.udph->uh_sum = 0; + p->l4.hdrs.udph->uh_sum = UDPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->l4.hdrs.udph, + (p->payload_len + UDP_HEADER_LEN), 0); } } diff --git a/src/util-unittest-helper.c b/src/util-unittest-helper.c index 10ad38f929..92c86ee49d 100644 --- a/src/util-unittest-helper.c +++ b/src/util-unittest-helper.c @@ -292,15 +292,16 @@ Packet *UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, int hdr_offset = sizeof(IPV4Hdr); switch (ipproto) { - case IPPROTO_UDP: - p->udph = (UDPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); - if (p->udph == NULL) + case IPPROTO_UDP: { + UDPHdr *udph = PacketSetUDP(p, (GET_PKT_DATA(p) + sizeof(IPV4Hdr))); + if (udph == NULL) goto error; - p->udph->uh_sport = sport; - p->udph->uh_dport = dport; + udph->uh_sport = sport; + udph->uh_dport = dport; hdr_offset += sizeof(UDPHdr); break; + } case IPPROTO_TCP: p->tcph = (TCPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); if (p->tcph == NULL) @@ -926,14 +927,16 @@ static int CheckUTHTestPacket(Packet *p, uint8_t ipproto) return 0; switch(ipproto) { - case IPPROTO_UDP: - if (p->udph == NULL) + case IPPROTO_UDP: { + const UDPHdr *udph = PacketGetUDP(p); + if (udph == NULL) return 0; - if (p->udph->uh_sport != sport) + if (udph->uh_sport != sport) return 0; - if (p->udph->uh_dport != dport) + if (udph->uh_dport != dport) return 0; break; + } case IPPROTO_TCP: if (p->tcph == NULL) return 0; diff --git a/src/util-validate.h b/src/util-validate.h index 4f4a46ec9e..8e7dc7bb38 100644 --- a/src/util-validate.h +++ b/src/util-validate.h @@ -75,7 +75,7 @@ if ((p)->proto == IPPROTO_TCP) { \ BUG_ON((p)->tcph == NULL); \ } else if ((p)->proto == IPPROTO_UDP) { \ - BUG_ON((p)->udph == NULL); \ + BUG_ON(PacketGetUDP((p)) == NULL); \ } else if ((p)->proto == IPPROTO_ICMP) { \ BUG_ON(PacketGetICMPv4((p)) == NULL); \ } else if ((p)->proto == IPPROTO_SCTP) { \