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.
pull/2624/head
Jason Ish 9 years ago committed by Victor Julien
parent ce8a65a58e
commit f56428d996

@ -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));
}

@ -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 */

@ -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];

@ -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 */

@ -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;

@ -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;

@ -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)

@ -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));

@ -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) {

@ -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);
}
}

Loading…
Cancel
Save