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.h" 30 #include "alias_local.h" 31 32 u_short 33 PacketAliasInternetChecksum(u_short *ptr, int nbytes) 34 { 35 int sum, oddbyte; 36 37 sum = 0; 38 while (nbytes > 1) 39 { 40 sum += *ptr++; 41 nbytes -= 2; 42 } 43 if (nbytes == 1) 44 { 45 oddbyte = 0; 46 *((u_char *) &oddbyte) = *(u_char *) ptr; 47 sum += oddbyte; 48 } 49 sum = (sum >> 16) + (sum & 0xffff); 50 sum += (sum >> 16); 51 return(~sum); 52 } 53 54 u_short 55 IpChecksum(struct ip *pip) 56 { 57 return( PacketAliasInternetChecksum((u_short *) pip, 58 (pip->ip_hl << 2)) ); 59 60 } 61 62 u_short 63 TcpChecksum(struct ip *pip) 64 { 65 u_short *ptr; 66 struct tcphdr *tc; 67 int nhdr, ntcp, nbytes; 68 int sum, oddbyte; 69 70 nhdr = pip->ip_hl << 2; 71 ntcp = ntohs(pip->ip_len) - nhdr; 72 73 tc = (struct tcphdr *) ((char *) pip + nhdr); 74 ptr = (u_short *) tc; 75 76 /* Add up TCP header and data */ 77 nbytes = ntcp; 78 sum = 0; 79 while (nbytes > 1) 80 { 81 sum += *ptr++; 82 nbytes -= 2; 83 } 84 if (nbytes == 1) 85 { 86 oddbyte = 0; 87 *((u_char *) &oddbyte) = *(u_char *) ptr; 88 sum += oddbyte; 89 } 90 91 /* "Pseudo-header" data */ 92 ptr = (u_short *) &(pip->ip_dst); 93 sum += *ptr++; 94 sum += *ptr; 95 ptr = (u_short *) &(pip->ip_src); 96 sum += *ptr++; 97 sum += *ptr; 98 sum += htons((u_short) ntcp); 99 sum += htons((u_short) pip->ip_p); 100 101 /* Roll over carry bits */ 102 sum = (sum >> 16) + (sum & 0xffff); 103 sum += (sum >> 16); 104 105 /* Return checksum */ 106 return((u_short) ~sum); 107 } 108 109 110 void 111 DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n) 112 { 113 int i; 114 int accumulate; 115 116 accumulate = *cksum; 117 for (i=0; i<n; i++) 118 { 119 accumulate -= *new++; 120 accumulate += *old++; 121 } 122 123 if (accumulate < 0) 124 { 125 accumulate = -accumulate; 126 accumulate = (accumulate >> 16) + (accumulate & 0xffff); 127 accumulate += accumulate >> 16; 128 *cksum = (u_short) ~accumulate; 129 } 130 else 131 { 132 accumulate = (accumulate >> 16) + (accumulate & 0xffff); 133 accumulate += accumulate >> 16; 134 *cksum = (u_short) accumulate; 135 } 136 } 137 138