Skip to content

Commit

Permalink
ipv4: update checksum function to be like tcp/udp
Browse files Browse the repository at this point in the history
Update the IPv4 checksum function to be like the
changed TCP/UDP checksum functions for consistency.
  • Loading branch information
jasonish authored and victorjulien committed Mar 27, 2017
1 parent b79a18e commit 6307890
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/alert-unified2-alert.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ static int Unified2PrintStreamSegmentCallback(const Packet *p, void *data, const

fakehdr->tcph.th_sum = TCPChecksum(fakehdr->ip4h.s_ip_addrs,
(uint16_t *)&fakehdr->tcph, buflen + sizeof(TCPHdr), 0);
fakehdr->ip4h.ip_csum = IPV4CalculateChecksum((uint16_t *)&fakehdr->ip4h,
IPV4_GET_RAW_HLEN(&fakehdr->ip4h));
fakehdr->ip4h.ip_csum = IPV4Checksum((uint16_t *)&fakehdr->ip4h,
IPV4_GET_RAW_HLEN(&fakehdr->ip4h), 0);
}

/* write out */
Expand Down
6 changes: 4 additions & 2 deletions src/decode-ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1199,7 +1199,8 @@ static int IPV4CalculateValidChecksumtest01(void)

csum = *( ((uint16_t *)raw_ipv4) + 5);

return (csum == IPV4CalculateChecksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4)));
FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) != 0);
PASS;
}

static int IPV4CalculateInvalidChecksumtest02(void)
Expand All @@ -1213,7 +1214,8 @@ static int IPV4CalculateInvalidChecksumtest02(void)

csum = *( ((uint16_t *)raw_ipv4) + 5);

return (csum != IPV4CalculateChecksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4)));
FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) == 0);
PASS;
}

/**
Expand Down
17 changes: 10 additions & 7 deletions src/decode-ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,24 @@ typedef struct IPV4Vars_
void DecodeIPV4RegisterTests(void);

/** ----- Inline functions ----- */
static inline uint16_t IPV4CalculateChecksum(uint16_t *, uint16_t);
static inline uint16_t IPV4Checksum(uint16_t *, uint16_t, uint16_t);

/**
* \brief Calculates the checksum for the IP packet
* \brief Calculateor validate the checksum for the IP packet
*
* \param pkt Pointer to the start of the IP packet
* \param hlen Length of the IP header
* \param init The current checksum if validating, 0 if generating.
*
* \retval csum Checksum for the IP packet
* \retval csum For validation 0 will be returned for success, for calculation
* this will be the checksum.
*/
static inline uint16_t IPV4CalculateChecksum(uint16_t *pkt, uint16_t hlen)
static inline uint16_t IPV4Checksum(uint16_t *pkt, uint16_t hlen, uint16_t init)
{
uint32_t csum = pkt[0];
uint32_t csum = init;

csum += pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[6] + pkt[7] + pkt[8] +
pkt[9];
csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[6] + pkt[7] +
pkt[8] + pkt[9];

hlen -= 20;
pkt += 10;
Expand Down
2 changes: 1 addition & 1 deletion src/defrag.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ BuildTestPacket(uint8_t proto, uint16_t id, uint16_t off, int mf,
SET_PKT_LEN(p, hlen + content_len);
SCFree(pcontent);

p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)GET_PKT_DATA(p), hlen);
p->ip4h->ip_csum = IPV4Checksum((uint16_t *)GET_PKT_DATA(p), hlen, 0);

/* Self test. */
if (IPV4_GET_VER(p) != 4)
Expand Down
9 changes: 5 additions & 4 deletions src/detect-csum.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,13 @@ static int DetectIPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
}

if (p->level3_comp_csum == -1)
p->level3_comp_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h,
IPV4_GET_HLEN(p));
p->level3_comp_csum = IPV4Checksum((uint16_t *)p->ip4h,
IPV4_GET_HLEN(p),
p->ip4h->ip_csum);

if (p->level3_comp_csum == p->ip4h->ip_csum && cd->valid == 1)
if (p->level3_comp_csum == 0 && cd->valid == 1)
return 1;
else if (p->level3_comp_csum != p->ip4h->ip_csum && cd->valid == 0)
else if (p->level3_comp_csum != 0 && cd->valid == 0)
return 1;
else
return 0;
Expand Down
4 changes: 2 additions & 2 deletions src/flow-timeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ static inline Packet *FlowForceReassemblyPseudoPacketSetup(Packet *p,
(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));
p->ip4h->ip_csum = IPV4Checksum((uint16_t *)p->ip4h,
IPV4_GET_RAW_HLEN(p->ip4h), 0);
} else if (FLOW_IS_IPV6(f)) {
p->tcph->th_sum = TCPChecksum(p->ip6h->s_ip6_addrs,
(uint16_t *)p->tcph, 20, 0);
Expand Down
4 changes: 2 additions & 2 deletions src/util-checksum.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ int ReCalculateChecksum(Packet *p)
}
/* IPV4 */
p->ip4h->ip_csum = 0;
p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h,
IPV4_GET_RAW_HLEN(p->ip4h));
p->ip4h->ip_csum = IPV4Checksum((uint16_t *)p->ip4h,
IPV4_GET_RAW_HLEN(p->ip4h), 0);
} else if (PKT_IS_IPV6(p)) {
/* just TCP for IPV6 */
if (PKT_IS_TCP(p)) {
Expand Down

0 comments on commit 6307890

Please sign in to comment.