alias_util.c revision 27864
1116742Ssam/* 2116904Ssam Alias_util.h contains general utilities used by other functions 3170360Ssam in the packet aliasing module. At the moment, there are functions 4116742Ssam for computing IP header and TCP packet checksums. 5116742Ssam 6116742Ssam The checksum routines are based upon example code in a Unix networking 7116742Ssam text written by Stevens (sorry, I can't remember the title -- but 8116742Ssam at least this is a good author). 9116742Ssam 10116742Ssam Initial Version: August, 1996 (cjm) 11116742Ssam 12116742Ssam Version 1.7: January 9, 1997 13116742Ssam Added differential checksum update function. 14116742Ssam*/ 15116904Ssam 16116904Ssam/* 17116904SsamNote: the checksum routines assume that the actual checksum word has 18116904Ssambeen zeroed out. If the checksum workd is filled with the proper value, 19116904Ssamthen these routines will give a result of zero (useful for testing 20116904Ssampurposes); 21116904Ssam*/ 22116904Ssam 23116904Ssam#include <sys/types.h> 24116904Ssam#include <netinet/in_systm.h> 25116904Ssam#include <netinet/in.h> 26116742Ssam#include <netinet/ip.h> 27116742Ssam#include <netinet/tcp.h> 28116742Ssam 29116742Ssam#include "alias.h" 30116742Ssam#include "alias_local.h" 31116742Ssam 32116742Ssamu_short 33116742SsamPacketAliasInternetChecksum(u_short *ptr, int nbytes) 34138568Ssam{ 35138568Ssam int sum, oddbyte; 36138568Ssam 37116742Ssam sum = 0; 38138568Ssam while (nbytes > 1) 39161146Ssam { 40138568Ssam sum += *ptr++; 41138568Ssam nbytes -= 2; 42170530Ssam } 43170530Ssam if (nbytes == 1) 44170530Ssam { 45170530Ssam oddbyte = 0; 46170530Ssam *((u_char *) &oddbyte) = *(u_char *) ptr; 47170530Ssam sum += oddbyte; 48170530Ssam } 49170530Ssam sum = (sum >> 16) + (sum & 0xffff); 50138568Ssam sum += (sum >> 16); 51170530Ssam return(~sum); 52170530Ssam} 53170530Ssam 54170530Ssamu_short 55170530SsamIpChecksum(struct ip *pip) 56170530Ssam{ 57170530Ssam return( PacketAliasInternetChecksum((u_short *) pip, 58170530Ssam (pip->ip_hl << 2)) ); 59170530Ssam 60170530Ssam} 61170530Ssam 62170530Ssamu_short 63173273SsamTcpChecksum(struct ip *pip) 64138568Ssam{ 65170530Ssam u_short *ptr; 66170530Ssam struct tcphdr *tc; 67170530Ssam int nhdr, ntcp, nbytes; 68170530Ssam int sum, oddbyte; 69170530Ssam 70170530Ssam nhdr = pip->ip_hl << 2; 71138568Ssam ntcp = ntohs(pip->ip_len) - nhdr; 72170530Ssam 73170530Ssam tc = (struct tcphdr *) ((char *) pip + nhdr); 74138568Ssam ptr = (u_short *) tc; 75170530Ssam 76138568Ssam/* Add up TCP header and data */ 77138568Ssam nbytes = ntcp; 78170530Ssam sum = 0; 79170530Ssam while (nbytes > 1) 80170530Ssam { 81170530Ssam sum += *ptr++; 82170530Ssam nbytes -= 2; 83170530Ssam } 84170530Ssam if (nbytes == 1) 85170530Ssam { 86138568Ssam oddbyte = 0; 87138568Ssam *((u_char *) &oddbyte) = *(u_char *) ptr; 88138568Ssam sum += oddbyte; 89138568Ssam } 90138568Ssam 91121180Ssam/* "Pseudo-header" data */ 92170530Ssam ptr = (u_short *) &(pip->ip_dst); 93170530Ssam sum += *ptr++; 94170530Ssam sum += *ptr; 95170530Ssam ptr = (u_short *) &(pip->ip_src); 96170530Ssam sum += *ptr++; 97170530Ssam sum += *ptr; 98170530Ssam sum += htons((u_short) ntcp); 99170530Ssam sum += htons((u_short) pip->ip_p); 100170530Ssam 101170530Ssam/* Roll over carry bits */ 102170530Ssam sum = (sum >> 16) + (sum & 0xffff); 103170530Ssam sum += (sum >> 16); 104170530Ssam 105170530Ssam/* Return checksum */ 106170530Ssam return((u_short) ~sum); 107170530Ssam} 108170530Ssam 109170530Ssam 110170530Ssamvoid 111170530SsamDifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n) 112170530Ssam{ 113170530Ssam int i; 114170530Ssam int accumulate; 115170530Ssam 116170530Ssam accumulate = *cksum; 117170530Ssam for (i=0; i<n; i++) 118170530Ssam { 119170530Ssam accumulate -= *new++; 120170530Ssam accumulate += *old++; 121170530Ssam } 122170530Ssam 123170530Ssam if (accumulate < 0) 124170530Ssam { 125170530Ssam accumulate = -accumulate; 126170530Ssam accumulate = (accumulate >> 16) + (accumulate & 0xffff); 127170530Ssam accumulate += accumulate >> 16; 128170530Ssam *cksum = (u_short) ~accumulate; 129170530Ssam } 130170530Ssam else 131170530Ssam { 132170530Ssam accumulate = (accumulate >> 16) + (accumulate & 0xffff); 133170530Ssam accumulate += accumulate >> 16; 134170530Ssam *cksum = (u_short) accumulate; 135170530Ssam } 136170530Ssam} 137170530Ssam 138170530Ssam