]>
Commit | Line | Data |
---|---|---|
b7080c8e A |
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 |