]> git.saurik.com Git - apple/network_cmds.git/blob - alias/alias_util.c
network_cmds-85.tar.gz
[apple/network_cmds.git] / alias / alias_util.c
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