1 /******************************************************************************
2 Author: Samuel Jero <sj323707@ohio.edu>
6 Description: IPv4 and IPv6 Checksum code
7 ******************************************************************************/
10 #include "checksums.h"
14 #define u_int32_t uint32_t
17 #define u_int16_t uint16_t
20 //Pseudo Headers for checksums
21 struct ip6_pseudo_hdr{
22 unsigned char src[IP6_ADDR_LEN];
23 unsigned char dest[IP6_ADDR_LEN];
25 unsigned char zero[3];
28 struct ip4_pseudo_hdr{
29 unsigned char src[IP4_ADDR_LEN];
30 unsigned char dest[IP4_ADDR_LEN];
32 unsigned char zero[3];
36 /*From http://gitorious.org/freebsd/freebsd/blobs/HEAD/sbin/dhclient/packet.c
38 u_int32_t checksum(unsigned char *buf, unsigned nbytes, u_int32_t sum)
41 /* Checksum all the pairs of bytes first... */
42 for (i = 0; i < (nbytes & ~1U); i += 2) {
43 sum += (u_int16_t)ntohs(*((u_int16_t *)(buf + i)));
48 * If there's a single byte left over, checksum it, too.
49 * Network byte order is big-endian, so the remaining byte is
60 /*From http://gitorious.org/freebsd/freebsd/blobs/HEAD/sbin/dhclient/packet.c
62 u_int32_t wrapsum(u_int32_t sum)
68 u_int16_t ipv6_pseudohdr_chksum(unsigned char* buff, int len, unsigned char* dest, unsigned char* src, int type){
69 struct ip6_pseudo_hdr hdr;
71 //create pseudo header
72 memset(&hdr, 0, sizeof(struct ip6_pseudo_hdr));
73 memcpy(hdr.src, src, IP6_ADDR_LEN);
74 memcpy(hdr.dest, dest, IP6_ADDR_LEN);
78 //calculate total checksum
79 return wrapsum(checksum((unsigned char*)&hdr,sizeof(struct ip6_pseudo_hdr),checksum(buff,len,0)));
82 u_int16_t ipv4_pseudohdr_chksum(unsigned char* buff, int len, unsigned char* dest, unsigned char* src, int type){
83 struct ip4_pseudo_hdr hdr;
85 //create pseudo header
86 memset(&hdr, 0, sizeof(struct ip4_pseudo_hdr));
87 memcpy(hdr.src, src, IP4_ADDR_LEN);
88 memcpy(hdr.dest, dest, IP4_ADDR_LEN);
92 //calculate total checksum
93 return wrapsum(checksum((unsigned char*)&hdr,sizeof(struct ip4_pseudo_hdr),checksum(buff,len,0)));
96 u_int16_t ipv4_chksum(unsigned char* buff, int len){
97 return wrapsum(checksum(buff,len,0));