X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fnet_utils.c;h=0a8a557319cf69aa096518e6fdab9a7e18011bf6;hb=b92b8f48fb47c48b3f9df91ea1009b5789d55e19;hp=ed5044c3deca90a05fee272cf119c4a4512dd2ed;hpb=ac1ca99926606faf5e2d37771680ed97d66ee5ab;p=platform%2Fkernel%2Fu-boot.git diff --git a/lib/net_utils.c b/lib/net_utils.c index ed5044c..0a8a557 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -10,6 +10,7 @@ */ #include +#include struct in_addr string_to_ip(const char *s) { @@ -56,3 +57,51 @@ void string_to_enetaddr(const char *addr, uint8_t *enetaddr) addr = (*end) ? end + 1 : end; } } + +uint compute_ip_checksum(const void *vptr, uint nbytes) +{ + int sum, oddbyte; + const unsigned short *ptr = vptr; + + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + ((u8 *)&oddbyte)[0] = *(u8 *)ptr; + ((u8 *)&oddbyte)[1] = 0; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + sum = ~sum & 0xffff; + + return sum; +} + +uint add_ip_checksums(uint offset, uint sum, uint new) +{ + ulong checksum; + + sum = ~sum & 0xffff; + new = ~new & 0xffff; + if (offset & 1) { + /* + * byte-swap the sum if it came from an odd offset; since the + * computation is endian-independent this works. + */ + new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); + } + checksum = sum + new; + if (checksum > 0xffff) + checksum -= 0xffff; + + return (~checksum) & 0xffff; +} + +int ip_checksum_ok(const void *addr, uint nbytes) +{ + return !(compute_ip_checksum(addr, nbytes) & 0xfffe); +}