lib: add internet checksum with pseudoheaders

Add convenience functions to compute the Internet checksum of a data
block, including a pseudoheader.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2019-01-22 22:39:47 +00:00
parent b523b2419e
commit 17b48d7d11
2 changed files with 44 additions and 1 deletions

View File

@ -46,6 +46,24 @@ int /* return checksum in low-order 16 bits */
return (answer);
}
int in_cksum_with_ph4(struct ipv4_ph *ph, void *data, int nbytes)
{
uint8_t dat[sizeof(struct ipv4_ph) + nbytes];
memcpy(dat, ph, sizeof(struct ipv4_ph));
memcpy(dat + sizeof(struct ipv4_ph), data, nbytes);
return in_cksum(dat, sizeof(dat));
}
int in_cksum_with_ph6(struct ipv6_ph *ph, void *data, int nbytes)
{
uint8_t dat[sizeof(struct ipv6_ph) + nbytes];
memcpy(dat, ph, sizeof(struct ipv6_ph));
memcpy(dat + sizeof(struct ipv6_ph), data, nbytes);
return in_cksum(dat, sizeof(dat));
}
/* Fletcher Checksum -- Refer to RFC1008. */
#define MODX 4102U /* 5802 should be fine */

View File

@ -1,8 +1,33 @@
#include <stdint.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int in_cksum(void *, int);
/* IPv4 pseudoheader */
struct ipv4_ph {
struct in_addr src;
struct in_addr dst;
uint8_t rsvd;
uint8_t proto;
uint16_t len;
} __attribute__((packed));
/* IPv6 pseudoheader */
struct ipv6_ph {
struct in6_addr src;
struct in6_addr dst;
uint32_t ulpl;
uint8_t zero[3];
uint8_t next_hdr;
} __attribute__((packed));
extern int in_cksum(void *data, int nbytes);
extern int in_cksum_with_ph4(struct ipv4_ph *ph, void *data, int nbytes);
extern int in_cksum_with_ph6(struct ipv6_ph *ph, void *data, int nbytes);
#define FLETCHER_CHECKSUM_VALIDATE 0xffff
extern uint16_t fletcher_checksum(uint8_t *, const size_t len,
const uint16_t offset);