1 /* 2 Alias_util.h contains general utilities used by other functions 3 in the packet aliasing module. At the moment, there are functions 4 for computing IP header and TCP packet checksums. 5 6 The checksum routines are based upon example code in a Unix networking 7 text written by Stevens (sorry, I can't remember the title -- but 8 at least this is a good author). 9 10 Initial Version: August, 1996 (cjm) 11 12 Version 1.7: January 9, 1997 13 Added differential checksum update function. 14 */ 15 16 /* 17 Note: the checksum routines assume that the actual checksum word has 18 been zeroed out. If the checksum workd is filled with the proper value, 19 then these routines will give a result of zero (useful for testing 20 purposes); 21 */ 22 23 #include <sys/types.h> 24 #include <netinet/in_systm.h> 25 #include <netinet/in.h> 26 #include <netinet/ip.h> 27 #include <netinet/tcp.h> 28 29 #include "alias_local.h" 30 31 u_short 32 InternetChecksum(u_short *ptr, int nbytes) 33 { 34 int sum, oddbyte; 35 36 sum = 0; 37 while (nbytes > 1) 38 { 39 sum += *ptr++; 40 nbytes -= 2; 41 } 42 if (nbytes == 1) 43 { 44 oddbyte = 0; 45 *((u_char *) &oddbyte) = *(u_char *) ptr; 46 sum += oddbyte; 47 } 48 sum = (sum >> 16) + (sum & 0xffff); 49 sum += (sum >> 16); 50 return(~sum); 51 } 52 53 u_short 54 IpChecksum(struct ip *pip) 55 { 56 return( InternetChecksum((u_short *) pip, (pip->ip_hl << 2)) ); 57 58 } 59 60 u_short 61 TcpChecksum(struct ip *pip) 62 { 63 u_short *ptr; 64 struct tcphdr *tc; 65 int nhdr, ntcp, nbytes; 66 int sum, oddbyte; 67 68 nhdr = pip->ip_hl << 2; 69 ntcp = ntohs(pip->ip_len) - nhdr; 70 71 tc = (struct tcphdr *) ((char *) pip + nhdr); 72 ptr = (u_short *) tc; 73 74 /* Add up TCP header and data */ 75 nbytes = ntcp; 76 sum = 0; 77 while (nbytes > 1) 78 { 79 sum += *ptr++; 80 nbytes -= 2; 81 } 82 if (nbytes == 1) 83 { 84 oddbyte = 0; 85 *((u_char *) &oddbyte) = *(u_char *) ptr; 86 sum += oddbyte; 87 } 88 89 /* "Pseudo-header" data */ 90 ptr = (u_short *) &(pip->ip_dst); 91 sum += *ptr++; 92 sum += *ptr; 93 ptr = (u_short *) &(pip->ip_src); 94 sum += *ptr++; 95 sum += *ptr; 96 sum += htons((u_short) ntcp); 97 sum += htons((u_short) pip->ip_p); 98 99 /* Roll over carry bits */ 100 sum = (sum >> 16) + (sum & 0xffff); 101 sum += (sum >> 16); 102 103 /* Return checksum */ 104 return((u_short) ~sum); 105 } 106 107 108 void 109 DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n) 110 { 111 int i; 112 int accumulate; 113 114 accumulate = *cksum; 115 for (i=0; i<n; i++) 116 { 117 accumulate -= *new++; 118 accumulate += *old++; 119 } 120 121 if (accumulate < 0) 122 { 123 accumulate = -accumulate; 124 accumulate = (accumulate >> 16) + (accumulate & 0xffff); 125 accumulate += accumulate >> 16; 126 *cksum = (u_short) ~accumulate; 127 } 128 else 129 { 130 accumulate = (accumulate >> 16) + (accumulate & 0xffff); 131 accumulate += accumulate >> 16; 132 *cksum = (u_short) accumulate; 133 } 134 } 135 136