alias_util.c revision 45926
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/* 17Note: the checksum routines assume that the actual checksum word has 18been zeroed out. If the checksum workd is filled with the proper value, 19then these routines will give a result of zero (useful for testing 20purposes); 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 32u_short 33PacketAliasInternetChecksum(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)[0] = *(u_char *) ptr; 47 ((u_char *) &oddbyte)[1] = 0; 48 sum += oddbyte; 49 } 50 sum = (sum >> 16) + (sum & 0xffff); 51 sum += (sum >> 16); 52 return(~sum); 53} 54 55u_short 56IpChecksum(struct ip *pip) 57{ 58 return( PacketAliasInternetChecksum((u_short *) pip, 59 (pip->ip_hl << 2)) ); 60 61} 62 63u_short 64TcpChecksum(struct ip *pip) 65{ 66 u_short *ptr; 67 struct tcphdr *tc; 68 int nhdr, ntcp, nbytes; 69 int sum, oddbyte; 70 71 nhdr = pip->ip_hl << 2; 72 ntcp = ntohs(pip->ip_len) - nhdr; 73 74 tc = (struct tcphdr *) ((char *) pip + nhdr); 75 ptr = (u_short *) tc; 76 77/* Add up TCP header and data */ 78 nbytes = ntcp; 79 sum = 0; 80 while (nbytes > 1) 81 { 82 sum += *ptr++; 83 nbytes -= 2; 84 } 85 if (nbytes == 1) 86 { 87 oddbyte = 0; 88 ((u_char *) &oddbyte)[0] = *(u_char *) ptr; 89 ((u_char *) &oddbyte)[1] = 0; 90 sum += oddbyte; 91 } 92 93/* "Pseudo-header" data */ 94 ptr = (u_short *) &(pip->ip_dst); 95 sum += *ptr++; 96 sum += *ptr; 97 ptr = (u_short *) &(pip->ip_src); 98 sum += *ptr++; 99 sum += *ptr; 100 sum += htons((u_short) ntcp); 101 sum += htons((u_short) pip->ip_p); 102 103/* Roll over carry bits */ 104 sum = (sum >> 16) + (sum & 0xffff); 105 sum += (sum >> 16); 106 107/* Return checksum */ 108 return((u_short) ~sum); 109} 110 111 112void 113DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n) 114{ 115 int i; 116 int accumulate; 117 118 accumulate = *cksum; 119 for (i=0; i<n; i++) 120 { 121 accumulate -= *new++; 122 accumulate += *old++; 123 } 124 125 if (accumulate < 0) 126 { 127 accumulate = -accumulate; 128 accumulate = (accumulate >> 16) + (accumulate & 0xffff); 129 accumulate += accumulate >> 16; 130 *cksum = (u_short) ~accumulate; 131 } 132 else 133 { 134 accumulate = (accumulate >> 16) + (accumulate & 0xffff); 135 accumulate += accumulate >> 16; 136 *cksum = (u_short) accumulate; 137 } 138} 139 140