Skip to content

Instantly share code, notes, and snippets.

@ijat
Forked from GreenRecycleBin/udp_checksum.c
Created September 25, 2018 06:08
Show Gist options
  • Save ijat/a0a05481725616482a688c640b11e821 to your computer and use it in GitHub Desktop.
Save ijat/a0a05481725616482a688c640b11e821 to your computer and use it in GitHub Desktop.
UDP checksum
uint16_t udp_checksum(struct udphdr *p_udp_header, size_t len, uint32_t src_addr, uint32_t dest_addr)
{
const uint16_t *buf = (const uint16_t*)p_udp_header;
uint16_t *ip_src = (void*)&src_addr, *ip_dst = (void*)&dest_addr;
uint32_t sum;
size_t length = len;
// Calculate the sum
sum = 0;
while (len > 1)
{
sum += *buf++;
if (sum & 0x80000000)
sum = (sum & 0xFFFF) + (sum >> 16);
len -= 2;
}
if (len & 1)
// Add the padding if the packet lenght is odd
sum += *((uint8_t*)buf);
// Add the pseudo-header
sum += *(ip_src++);
sum += *ip_src;
sum += *(ip_dst++);
sum += *ip_dst;
sum += htons(IPPROTO_UDP);
sum += htons(length);
// Add the carries
while (sum >> 16)
sum = (sum & 0xFFFF) + (sum >> 16);
// Return the one's complement of sum
return (uint16_t)~sum;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment