#include "checksum.h"
#include "macros.h"
#include "nethelp.h"
/**
* @brief generate an IP style checksum
* @param[in] ptr pointer to data
* @param[in] sz size of data
* @param[in] pseudo1 additional value to include - set to 0 if not needed
* @param[in] preude2 additional value to include - set to 0 if not needed
*
* can also be used to check a checksum (returns 0 if correct)
*/
unsigned short checksum(void *ptr, unsigned int sz,
unsigned short pseudo1, unsigned short pseudo2)
{
unsigned int sum;
unsigned short *data;
// sum up data of pseudo header
sum = pseudo1;
sum += pseudo2;
// add full 16 bit words in header
for (data = ptr; sz >= 2; data++, sz -= 2)
sum += ntohs(*data);
// add last byte
if (sz >= 1)
sum += *(unsigned char *)data << 8;
// convert sum to one's complement sum
// add carries (bits 31..16) to sum (bits 15..0)
sum = (sum & 0x0000FFFF) + (sum >> 16);
// still a carry possible (from last addition)
sum = (sum & 0x0000FFFF) + (sum >> 16);
// return complement of one's complement sum
return ~(unsigned short)sum;
}