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