From: Jason Ish Date: Fri, 17 Feb 2017 22:04:23 +0000 (-0600) Subject: tcp/udp: fix checksum validation when 0xffff X-Git-Tag: suricata-4.0.0-beta1~247 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f56428d996542f27b66ba1cda2477af2a24c50e9;p=thirdparty%2Fsuricata.git tcp/udp: fix checksum validation when 0xffff Issue: https://redmine.openinfosecfoundation.org/issues/2041 One approach to fixing this issue to just validate the checksum instead of regenerating it and comparing it. This method is used in some kernels and other network tools. When validating, the current checksum is passed in as an initial argument which will cause the final checksum to be 0 if OK. If generating a checksum, 0 is passed and the result is the generated checksum. --- diff --git a/src/alert-unified2-alert.c b/src/alert-unified2-alert.c index e29549160d..44dcb4d834 100644 --- a/src/alert-unified2-alert.c +++ b/src/alert-unified2-alert.c @@ -634,12 +634,12 @@ static int Unified2PrintStreamSegmentCallback(const Packet *p, void *data, const FakeIPv6Hdr *fakehdr = (FakeIPv6Hdr *)aun->iphdr; fakehdr->tcph.th_sum = TCPV6CalculateChecksum(fakehdr->ip6h.s_ip6_addrs, - (uint16_t *)&fakehdr->tcph, buflen + sizeof(TCPHdr)); + (uint16_t *)&fakehdr->tcph, buflen + sizeof(TCPHdr), 0); } else { FakeIPv4Hdr *fakehdr = (FakeIPv4Hdr *)aun->iphdr; fakehdr->tcph.th_sum = TCPCalculateChecksum(fakehdr->ip4h.s_ip_addrs, - (uint16_t *)&fakehdr->tcph, buflen + sizeof(TCPHdr)); + (uint16_t *)&fakehdr->tcph, buflen + sizeof(TCPHdr), 0); fakehdr->ip4h.ip_csum = IPV4CalculateChecksum((uint16_t *)&fakehdr->ip4h, IPV4_GET_RAW_HLEN(&fakehdr->ip4h)); } diff --git a/src/decode-tcp.c b/src/decode-tcp.c index 51dbfaaa26..75e52c27fd 100644 --- a/src/decode-tcp.c +++ b/src/decode-tcp.c @@ -236,8 +236,9 @@ static int TCPCalculateValidChecksumtest01(void) csum = *( ((uint16_t *)raw_tcp) + 8); - return (csum == TCPCalculateChecksum((uint16_t *) raw_ipshdr, - (uint16_t *)raw_tcp, sizeof(raw_tcp))); + FAIL_IF(TCPCalculateChecksum((uint16_t *)raw_ipshdr, + (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) != 0); + PASS; } static int TCPCalculateInvalidChecksumtest02(void) @@ -256,8 +257,9 @@ static int TCPCalculateInvalidChecksumtest02(void) csum = *( ((uint16_t *)raw_tcp) + 8); - return (csum != TCPCalculateChecksum((uint16_t *) raw_ipshdr, - (uint16_t *)raw_tcp, sizeof(raw_tcp))); + FAIL_IF(TCPCalculateChecksum((uint16_t *) raw_ipshdr, + (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) == 0); + PASS; } static int TCPV6CalculateValidChecksumtest03(void) @@ -279,8 +281,9 @@ static int TCPV6CalculateValidChecksumtest03(void) csum = *( ((uint16_t *)(raw_ipv6 + 70))); - return (csum == TCPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 32)); + FAIL_IF(TCPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), + (uint16_t *)(raw_ipv6 + 54), 32, csum) != 0); + PASS; } static int TCPV6CalculateInvalidChecksumtest04(void) @@ -302,8 +305,9 @@ static int TCPV6CalculateInvalidChecksumtest04(void) csum = *( ((uint16_t *)(raw_ipv6 + 70))); - return (csum != TCPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 32)); + FAIL_IF(TCPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), + (uint16_t *)(raw_ipv6 + 54), 32, csum) == 0); + PASS; } /** \test Get the wscale of 2 */ diff --git a/src/decode-tcp.h b/src/decode-tcp.h index c544036bd4..38b27f6b38 100644 --- a/src/decode-tcp.h +++ b/src/decode-tcp.h @@ -164,26 +164,30 @@ typedef struct TCPVars_ void DecodeTCPRegisterTests(void); /** -------- Inline functions ------- */ -static inline uint16_t TCPCalculateChecksum(uint16_t *, uint16_t *, uint16_t); -static inline uint16_t TCPV6CalculateChecksum(uint16_t *, uint16_t *, uint16_t); +static inline uint16_t TCPCalculateChecksum(uint16_t *, uint16_t *, uint16_t, + uint16_t); +static inline uint16_t TCPV6CalculateChecksum(uint16_t *, uint16_t *, uint16_t, + uint16_t); /** - * \brief Calculates the checksum for the TCP packet + * \brief Calculate or validate the checksum for the TCP packet * * \param shdr Pointer to source address field from the IP packet. Used as a * part of the pseudoheader for computing the checksum * \param pkt Pointer to the start of the TCP packet * \param tlen Total length of the TCP packet(header + payload) + * \param init The current checksum if validating, 0 if generating. * - * \retval csum Checksum for the TCP packet + * \retval csum For validation 0 will be returned for success, for calculation + * this will be the checksum. */ static inline uint16_t TCPCalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) + uint16_t tlen, uint16_t init) { uint16_t pad = 0; - uint32_t csum = shdr[0]; + uint32_t csum = init; - csum += shdr[1] + shdr[2] + shdr[3] + htons(6) + htons(tlen); + csum += shdr[0] + shdr[1] + shdr[2] + shdr[3] + htons(6) + htons(tlen); csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + pkt[7] + pkt[9]; @@ -193,7 +197,9 @@ static inline uint16_t TCPCalculateChecksum(uint16_t *shdr, uint16_t *pkt, while (tlen >= 32) { csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + + pkt[7] + + pkt[8] + + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + pkt[14] + pkt[15]; tlen -= 32; pkt += 16; @@ -229,24 +235,26 @@ static inline uint16_t TCPCalculateChecksum(uint16_t *shdr, uint16_t *pkt, } /** - * \brief Calculates the checksum for the TCP packet + * \brief Calculate or validate the checksum for the TCP packet * * \param shdr Pointer to source address field from the IPV6 packet. Used as a * part of the psuedoheader for computing the checksum * \param pkt Pointer to the start of the TCP packet * \param tlen Total length of the TCP packet(header + payload) + * \param init The current checksum if validating, 0 if generating. * - * \retval csum Checksum for the TCP packet + * \retval csum For validation 0 will be returned for success, for calculation + * this will be the checksum. */ static inline uint16_t TCPV6CalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) + uint16_t tlen, uint16_t init) { uint16_t pad = 0; - uint32_t csum = shdr[0]; + uint32_t csum = init; - csum += shdr[1] + shdr[2] + shdr[3] + shdr[4] + shdr[5] + shdr[6] + - shdr[7] + shdr[8] + shdr[9] + shdr[10] + shdr[11] + shdr[12] + - shdr[13] + shdr[14] + shdr[15] + htons(6) + htons(tlen); + csum += shdr[0] + shdr[1] + shdr[2] + shdr[3] + shdr[4] + shdr[5] + + shdr[6] + shdr[7] + shdr[8] + shdr[9] + shdr[10] + shdr[11] + + shdr[12] + shdr[13] + shdr[14] + shdr[15] + htons(6) + htons(tlen); csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + pkt[7] + pkt[9]; diff --git a/src/decode-udp.c b/src/decode-udp.c index d45d57f254..50ca2397fa 100644 --- a/src/decode-udp.c +++ b/src/decode-udp.c @@ -117,9 +117,9 @@ static int UDPV4CalculateValidChecksumtest01(void) csum = *( ((uint16_t *)raw_udp) + 3); - return (csum == UDPV4CalculateChecksum((uint16_t *) raw_ipshdr, - (uint16_t *)raw_udp, - sizeof(raw_udp))); + FAIL_IF(UDPV4CalculateChecksum((uint16_t *) raw_ipshdr, + (uint16_t *)raw_udp, sizeof(raw_udp), csum) != 0); + PASS; } static int UDPV4CalculateInvalidChecksumtest02(void) @@ -144,9 +144,9 @@ static int UDPV4CalculateInvalidChecksumtest02(void) csum = *( ((uint16_t *)raw_udp) + 3); - return (csum != UDPV4CalculateChecksum((uint16_t *) raw_ipshdr, - (uint16_t *)raw_udp, - sizeof(raw_udp))); + FAIL_IF(UDPV4CalculateChecksum((uint16_t *) raw_ipshdr, + (uint16_t *)raw_udp, sizeof(raw_udp), csum) == 0); + PASS; } static int UDPV6CalculateValidChecksumtest03(void) @@ -167,8 +167,9 @@ static int UDPV6CalculateValidChecksumtest03(void) csum = *( ((uint16_t *)(raw_ipv6 + 60))); - return (csum == UDPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 20)); + FAIL_IF(UDPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), + (uint16_t *)(raw_ipv6 + 54), 20, csum) != 0); + PASS; } static int UDPV6CalculateInvalidChecksumtest04(void) @@ -189,8 +190,9 @@ static int UDPV6CalculateInvalidChecksumtest04(void) csum = *( ((uint16_t *)(raw_ipv6 + 60))); - return (csum != UDPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 20)); + FAIL_IF(UDPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), + (uint16_t *)(raw_ipv6 + 54), 20, csum) == 0); + PASS; } #endif /* UNITTESTS */ diff --git a/src/decode-udp.h b/src/decode-udp.h index 027938f094..cc04fa7f81 100644 --- a/src/decode-udp.h +++ b/src/decode-udp.h @@ -54,26 +54,31 @@ typedef struct UDPHdr_ void DecodeUDPV4RegisterTests(void); /** ------ Inline function ------ */ -static inline uint16_t UDPV4CalculateChecksum(uint16_t *, uint16_t *, uint16_t); -static inline uint16_t UDPV6CalculateChecksum(uint16_t *, uint16_t *, uint16_t); +static inline uint16_t UDPV4CalculateChecksum(uint16_t *, uint16_t *, uint16_t, + uint16_t); +static inline uint16_t UDPV6CalculateChecksum(uint16_t *, uint16_t *, uint16_t, + uint16_t); /** - * \brief Calculates the checksum for the UDP packet + * \brief Calculate or valid the checksum for the UDP packet * * \param shdr Pointer to source address field from the IP packet. Used as a * part of the psuedoheader for computing the checksum * \param pkt Pointer to the start of the UDP packet * \param hlen Total length of the UDP packet(header + payload) + * \param init For validation this is the UDP checksum, for calculation this + * value should be set to 0. * - * \retval csum Checksum for the UDP packet + * \retval csum For validation 0 will be returned for success, for calculation + * this will be the checksum. */ static inline uint16_t UDPV4CalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) + uint16_t tlen, uint16_t init) { uint16_t pad = 0; - uint32_t csum = shdr[0]; + uint32_t csum = init; - csum += shdr[1] + shdr[2] + shdr[3] + htons(17) + htons(tlen); + csum += shdr[0] + shdr[1] + shdr[2] + shdr[3] + htons(17) + htons(tlen); csum += pkt[0] + pkt[1] + pkt[2]; @@ -115,29 +120,32 @@ static inline uint16_t UDPV4CalculateChecksum(uint16_t *shdr, uint16_t *pkt, csum += (csum >> 16); uint16_t csum_u16 = (uint16_t)~csum; - if (csum_u16 == 0) + if (init == 0 && csum_u16 == 0) return 0xFFFF; else return csum_u16; } /** - * \brief Calculates the checksum for the UDP packet + * \brief Calculate or valid the checksum for the UDP packet * * \param shdr Pointer to source address field from the IPV6 packet. Used as a * part of the psuedoheader for computing the checksum * \param pkt Pointer to the start of the UDP packet * \param tlen Total length of the UDP packet(header + payload) + * \param init For validation this is the UDP checksum, for calculation this + * value should be set to 0. * - * \retval csum Checksum for the UDP packet + * \retval csum For validation 0 will be returned for success, for calculation + * this will be the checksum. */ static inline uint16_t UDPV6CalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) + uint16_t tlen, uint16_t init) { uint16_t pad = 0; - uint32_t csum = shdr[0]; + uint32_t csum = init; - csum += shdr[1] + shdr[2] + shdr[3] + shdr[4] + shdr[5] + shdr[6] + + csum += shdr[0] + shdr[1] + shdr[2] + shdr[3] + shdr[4] + shdr[5] + shdr[6] + shdr[7] + shdr[8] + shdr[9] + shdr[10] + shdr[11] + shdr[12] + shdr[13] + shdr[14] + shdr[15] + htons(17) + htons(tlen); @@ -181,7 +189,7 @@ static inline uint16_t UDPV6CalculateChecksum(uint16_t *shdr, uint16_t *pkt, csum += (csum >> 16); uint16_t csum_u16 = (uint16_t)~csum; - if (csum_u16 == 0) + if (init == 0 && csum_u16 == 0) return 0xFFFF; else return csum_u16; diff --git a/src/detect-csum.c b/src/detect-csum.c index a7e5d9ba4a..8e3d69391b 100644 --- a/src/detect-csum.c +++ b/src/detect-csum.c @@ -338,11 +338,13 @@ static int DetectTCPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, if (p->level4_comp_csum == -1) p->level4_comp_csum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, (uint16_t *)p->tcph, - (p->payload_len + TCP_GET_HLEN(p))); + (p->payload_len + + TCP_GET_HLEN(p)), + p->tcph->th_sum); - if (p->level4_comp_csum == p->tcph->th_sum && cd->valid == 1) + if (p->level4_comp_csum == 0 && cd->valid == 1) return 1; - else if (p->level4_comp_csum != p->tcph->th_sum && cd->valid == 0) + else if (p->level4_comp_csum != 0 && cd->valid == 0) return 1; else return 0; @@ -433,11 +435,13 @@ static int DetectTCPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, if (p->level4_comp_csum == -1) p->level4_comp_csum = TCPV6CalculateChecksum(p->ip6h->s_ip6_addrs, (uint16_t *)p->tcph, - (p->payload_len + TCP_GET_HLEN(p))); + (p->payload_len + + TCP_GET_HLEN(p)), + p->tcph->th_sum); - if (p->level4_comp_csum == p->tcph->th_sum && cd->valid == 1) + if (p->level4_comp_csum == 0 && cd->valid == 1) return 1; - else if (p->level4_comp_csum != p->tcph->th_sum && cd->valid == 0) + else if (p->level4_comp_csum != 0 && cd->valid == 0) return 1; else return 0; @@ -529,11 +533,12 @@ static int DetectUDPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, p->level4_comp_csum = UDPV4CalculateChecksum(p->ip4h->s_ip_addrs, (uint16_t *)p->udph, (p->payload_len + - UDP_HEADER_LEN) ); + UDP_HEADER_LEN), + p->udph->uh_sum); - if (p->level4_comp_csum == p->udph->uh_sum && cd->valid == 1) + if (p->level4_comp_csum == 0 && cd->valid == 1) return 1; - else if (p->level4_comp_csum != p->udph->uh_sum && cd->valid == 0) + else if (p->level4_comp_csum != 0 && cd->valid == 0) return 1; else return 0; @@ -625,11 +630,12 @@ static int DetectUDPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, p->level4_comp_csum = UDPV6CalculateChecksum(p->ip6h->s_ip6_addrs, (uint16_t *)p->udph, (p->payload_len + - UDP_HEADER_LEN) ); + UDP_HEADER_LEN), + p->udph->uh_sum); - if (p->level4_comp_csum == p->udph->uh_sum && cd->valid == 1) + if (p->level4_comp_csum == 0 && cd->valid == 1) return 1; - else if (p->level4_comp_csum != p->udph->uh_sum && cd->valid == 0) + else if (p->level4_comp_csum != 0 && cd->valid == 0) return 1; else return 0; diff --git a/src/detect.c b/src/detect.c index d30b7905c9..3ccb3b8e99 100644 --- a/src/detect.c +++ b/src/detect.c @@ -5821,7 +5821,6 @@ int SigTest26TCPV4Keyword(void) ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; memset(&th_v, 0, sizeof(ThreadVars)); memset(p1, 0, SIZE_OF_PACKET); @@ -5852,9 +5851,7 @@ int SigTest26TCPV4Keyword(void) p2->proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } + FAIL_IF_NULL(de_ctx); de_ctx->flags |= DE_QUIET; @@ -5862,43 +5859,31 @@ int SigTest26TCPV4Keyword(void) "alert ip any any -> any any " "(content:\"|DE 01 03|\"; tcpv4-csum:valid; dsize:20; " "msg:\"tcpv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } + FAIL_IF_NULL(de_ctx->sig_list); de_ctx->sig_list->next = SigInit(de_ctx, "alert ip any any -> any any " "(content:\"|DE 01 03|\"; tcpv4-csum:invalid; " "msg:\"tcpv4-csum keyword check(1)\"; " "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto end; - } + FAIL_IF_NULL(de_ctx->sig_list->next); SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!(PacketAlertCheck(p1, 1))) { - printf("sig 1 didn't match: "); - goto end; - } + FAIL_IF(!(PacketAlertCheck(p1, 1))); SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 2))) { - printf("sig 2 didn't match: "); - goto end; - } + FAIL_IF(!(PacketAlertCheck(p2, 2))); - result = 1; -end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); SCFree(p1); SCFree(p2); - return result; + PASS; } /* Test SigTest26TCPV4Keyword but also check for invalid IPV4 checksum */ @@ -6543,16 +6528,12 @@ int SigTest30UDPV4Keyword(void) 0x67, 0x6c, 0x65, 0xc0, 0x27}; Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; + FAIL_IF_NULL(p1); Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } + FAIL_IF_NULL(p2); + ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0yyyyyyyyyyyyyyyy\r\n" "\r\n\r\nyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"; @@ -6580,9 +6561,7 @@ int SigTest30UDPV4Keyword(void) p2->proto = IPPROTO_UDP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } + FAIL_IF_NULL(de_ctx); de_ctx->flags |= DE_QUIET; @@ -6591,45 +6570,32 @@ int SigTest30UDPV4Keyword(void) "(content:\"/one/\"; udpv4-csum:valid; " "msg:\"udpv4-csum keyword check(1)\"; " "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } + FAIL_IF_NULL(de_ctx->sig_list); de_ctx->sig_list->next = SigInit(de_ctx, "alert udp any any -> any any " "(content:\"/one/\"; udpv4-csum:invalid; " "msg:\"udpv4-csum keyword check(1)\"; " "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } + FAIL_IF_NULL(de_ctx->sig_list->next); SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 1; - else - result &= 0; + FAIL_IF_NOT(PacketAlertCheck(p1, 1)); SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 1; - else - result &= 0; + FAIL_IF_NOT(PacketAlertCheck(p2, 2)); SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); -end: SCFree(p1); SCFree(p2); - return result; + PASS; } int SigTest31NegativeUDPV4Keyword(void) @@ -6783,16 +6749,12 @@ int SigTest32UDPV6Keyword(void) 0x09, 0x01}; Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; + FAIL_IF_NULL(p1); Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } + FAIL_IF_NULL(p2); + ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; uint8_t *buf = (uint8_t *)"GET /one/ HTTP\r\n" "\r\n\r\n"; @@ -6820,9 +6782,7 @@ int SigTest32UDPV6Keyword(void) p2->proto = IPPROTO_UDP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } + FAIL_IF_NULL(de_ctx); de_ctx->flags |= DE_QUIET; @@ -6830,45 +6790,33 @@ int SigTest32UDPV6Keyword(void) "alert udp any any -> any any " "(content:\"/one/\"; udpv6-csum:valid; " "msg:\"udpv6-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } + FAIL_IF_NULL(de_ctx->sig_list); de_ctx->sig_list->next = SigInit(de_ctx, "alert udp any any -> any any " "(content:\"/one/\"; udpv6-csum:invalid; " "msg:\"udpv6-csum keyword check(1)\"; " "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } + FAIL_IF_NULL(de_ctx->sig_list->next); SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 1; - else - result &= 0; + FAIL_IF_NOT(PacketAlertCheck(p1, 1)); SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 1; - else - result &= 0; + FAIL_IF_NOT(PacketAlertCheck(p2, 2)); SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); -end: + SCFree(p1); SCFree(p2); - return result; + PASS; } int SigTest33NegativeUDPV6Keyword(void) diff --git a/src/flow-timeout.c b/src/flow-timeout.c index e62ccd4a2e..c835413076 100644 --- a/src/flow-timeout.c +++ b/src/flow-timeout.c @@ -240,14 +240,14 @@ static inline Packet *FlowForceReassemblyPseudoPacketSetup(Packet *p, if (FLOW_IS_IPV4(f)) { p->tcph->th_sum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->tcph, 20); + (uint16_t *)p->tcph, 20, 0); /* calc ipv4 csum as we may log it and barnyard might reject * a wrong checksum */ p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h, IPV4_GET_RAW_HLEN(p->ip4h)); } else if (FLOW_IS_IPV6(f)) { p->tcph->th_sum = TCPCalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, 20); + (uint16_t *)p->tcph, 20, 0); } memset(&p->ts, 0, sizeof(struct timeval)); diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 2223548fbd..aa748701a8 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -4710,18 +4710,19 @@ static inline int StreamTcpValidateChecksum(Packet *p) p->level4_comp_csum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, (uint16_t *)p->tcph, (p->payload_len + - TCP_GET_HLEN(p))); + TCP_GET_HLEN(p)), + p->tcph->th_sum); } else if (PKT_IS_IPV6(p)) { p->level4_comp_csum = TCPV6CalculateChecksum(p->ip6h->s_ip6_addrs, (uint16_t *)p->tcph, (p->payload_len + - TCP_GET_HLEN(p))); + TCP_GET_HLEN(p)), + p->tcph->th_sum); } } - if (p->level4_comp_csum != p->tcph->th_sum) { + if (p->level4_comp_csum != 0) { ret = 0; - SCLogDebug("Checksum of received packet %p is invalid",p); if (p->livedev) { (void) SC_ATOMIC_ADD(p->livedev->invalid_checksums, 1); } else if (p->pcap_cnt) { diff --git a/src/util-checksum.c b/src/util-checksum.c index 455e2f52aa..8c1c39131d 100644 --- a/src/util-checksum.c +++ b/src/util-checksum.c @@ -34,11 +34,11 @@ int ReCalculateChecksum(Packet *p) /* TCP */ p->tcph->th_sum = 0; p->tcph->th_sum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p))); + (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); } else if (PKT_IS_UDP(p)) { p->udph->uh_sum = 0; p->udph->uh_sum = UDPV4CalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN)); + (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0); } /* IPV4 */ p->ip4h->ip_csum = 0; @@ -49,11 +49,11 @@ int ReCalculateChecksum(Packet *p) if (PKT_IS_TCP(p)) { p->tcph->th_sum = 0; p->tcph->th_sum = TCPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p))); + (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); } else if (PKT_IS_UDP(p)) { p->udph->uh_sum = 0; p->udph->uh_sum = UDPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN)); + (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0); } }