39 lines
		
	
	
		
			898 B
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			39 lines
		
	
	
		
			898 B
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Checksum routine for Internet Protocol family headers (C Version)
 | 
						|
 *
 | 
						|
 * Licensed under GPLv2, see file LICENSE in this source tree.
 | 
						|
 */
 | 
						|
 | 
						|
#include "libbb.h"
 | 
						|
 | 
						|
uint16_t FAST_FUNC inet_cksum(const void *ptr, int nleft)
 | 
						|
{
 | 
						|
	const uint16_t *addr = ptr;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Our algorithm is simple, using a 32 bit accumulator,
 | 
						|
	 * we add sequential 16 bit words to it, and at the end, fold
 | 
						|
	 * back all the carry bits from the top 16 bits into the lower
 | 
						|
	 * 16 bits.
 | 
						|
	 */
 | 
						|
	unsigned sum = 0;
 | 
						|
	while (nleft > 1) {
 | 
						|
		sum += *addr++;
 | 
						|
		nleft -= 2;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Mop up an odd byte, if necessary */
 | 
						|
	if (nleft == 1) {
 | 
						|
		if (BB_LITTLE_ENDIAN)
 | 
						|
			sum += *(uint8_t*)addr;
 | 
						|
		else
 | 
						|
			sum += *(uint8_t*)addr << 8;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Add back carry outs from top 16 bits to low 16 bits */
 | 
						|
	sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
 | 
						|
	sum += (sum >> 16);                     /* add carry */
 | 
						|
 | 
						|
	return (uint16_t)~sum;
 | 
						|
}
 |