00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef __CHECKSUM_H__
00031 #define __CHECKSUM_H__
00032
00033 #ifdef HAVE_CONFIG_H
00034 #include "config.h"
00035 #endif
00036
00037 #include <sys/types.h>
00038
00039
00040
00041 #define CSE_IP 0x01
00042 #define CSE_TCP 0x02
00043 #define CSE_UDP 0x04
00044 #define CSE_ICMP 0x08
00045 #define CSE_IGMP 0x10
00046
00047
00048
00049
00050
00051
00052
00053
00054 static inline unsigned short in_chksum_ip( unsigned short * w, int blen )
00055 {
00056 unsigned int cksum;
00057
00058
00059 cksum = w[0];
00060 cksum += w[1];
00061 cksum += w[2];
00062 cksum += w[3];
00063 cksum += w[4];
00064 cksum += w[5];
00065 cksum += w[6];
00066 cksum += w[7];
00067 cksum += w[8];
00068 cksum += w[9];
00069
00070 blen -= 20;
00071 w += 10;
00072
00073 while( blen )
00074 {
00075 cksum += w[0];
00076 cksum += w[1];
00077 w += 2;
00078 blen -= 4;
00079 }
00080
00081 cksum = (cksum >> 16) + (cksum & 0x0000ffff);
00082 cksum += (cksum >> 16);
00083
00084 return (unsigned short) (~cksum);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 static inline unsigned short in_chksum_tcp( unsigned short *h, unsigned short * d, int dlen )
00097 {
00098 unsigned int cksum;
00099 unsigned short answer=0;
00100
00101
00102 cksum = h[0];
00103 cksum += h[1];
00104 cksum += h[2];
00105 cksum += h[3];
00106 cksum += h[4];
00107 cksum += h[5];
00108
00109
00110 cksum += d[0];
00111 cksum += d[1];
00112 cksum += d[2];
00113 cksum += d[3];
00114 cksum += d[4];
00115 cksum += d[5];
00116 cksum += d[6];
00117 cksum += d[7];
00118 cksum += d[8];
00119 cksum += d[9];
00120
00121 dlen -= 20;
00122 d += 10;
00123
00124 while(dlen >=32)
00125 {
00126 cksum += d[0];
00127 cksum += d[1];
00128 cksum += d[2];
00129 cksum += d[3];
00130 cksum += d[4];
00131 cksum += d[5];
00132 cksum += d[6];
00133 cksum += d[7];
00134 cksum += d[8];
00135 cksum += d[9];
00136 cksum += d[10];
00137 cksum += d[11];
00138 cksum += d[12];
00139 cksum += d[13];
00140 cksum += d[14];
00141 cksum += d[15];
00142 d += 16;
00143 dlen -= 32;
00144 }
00145
00146 while(dlen >=8)
00147 {
00148 cksum += d[0];
00149 cksum += d[1];
00150 cksum += d[2];
00151 cksum += d[3];
00152 d += 4;
00153 dlen -= 8;
00154 }
00155
00156 while(dlen > 1)
00157 {
00158 cksum += *d++;
00159 dlen -= 2;
00160 }
00161
00162 if( dlen == 1 )
00163 {
00164
00165 *(unsigned char*)(&answer) = (*(unsigned char*)d);
00166
00167
00168
00169 cksum += answer;
00170 }
00171
00172 cksum = (cksum >> 16) + (cksum & 0x0000ffff);
00173 cksum += (cksum >> 16);
00174
00175 return (unsigned short)(~cksum);
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 static inline unsigned short in_chksum_udp( unsigned short *h, unsigned short * d, int dlen )
00187 {
00188 unsigned int cksum;
00189 unsigned short answer=0;
00190
00191
00192 cksum = h[0];
00193 cksum += h[1];
00194 cksum += h[2];
00195 cksum += h[3];
00196 cksum += h[4];
00197 cksum += h[5];
00198
00199
00200 cksum += d[0];
00201 cksum += d[1];
00202 cksum += d[2];
00203 cksum += d[3];
00204
00205 dlen -= 8;
00206 d += 4;
00207
00208 while(dlen >=32)
00209 {
00210 cksum += d[0];
00211 cksum += d[1];
00212 cksum += d[2];
00213 cksum += d[3];
00214 cksum += d[4];
00215 cksum += d[5];
00216 cksum += d[6];
00217 cksum += d[7];
00218 cksum += d[8];
00219 cksum += d[9];
00220 cksum += d[10];
00221 cksum += d[11];
00222 cksum += d[12];
00223 cksum += d[13];
00224 cksum += d[14];
00225 cksum += d[15];
00226 d += 16;
00227 dlen -= 32;
00228 }
00229
00230 while(dlen >=8)
00231 {
00232 cksum += d[0];
00233 cksum += d[1];
00234 cksum += d[2];
00235 cksum += d[3];
00236 d += 4;
00237 dlen -= 8;
00238 }
00239
00240 while(dlen > 1)
00241 {
00242 cksum += *d++;
00243 dlen -= 2;
00244 }
00245
00246 if( dlen == 1 )
00247 {
00248 *(unsigned char*)(&answer) = (*(unsigned char*)d);
00249 cksum += answer;
00250 }
00251
00252 cksum = (cksum >> 16) + (cksum & 0x0000ffff);
00253 cksum += (cksum >> 16);
00254
00255 return (unsigned short)(~cksum);
00256 }
00257
00258
00259
00260
00261 static inline unsigned short in_chksum_icmp( unsigned short * w, int blen )
00262 {
00263 unsigned short answer=0;
00264 unsigned int cksum = 0;
00265
00266 while(blen >=32)
00267 {
00268 cksum += w[0];
00269 cksum += w[1];
00270 cksum += w[2];
00271 cksum += w[3];
00272 cksum += w[4];
00273 cksum += w[5];
00274 cksum += w[6];
00275 cksum += w[7];
00276 cksum += w[8];
00277 cksum += w[9];
00278 cksum += w[10];
00279 cksum += w[11];
00280 cksum += w[12];
00281 cksum += w[13];
00282 cksum += w[14];
00283 cksum += w[15];
00284 w += 16;
00285 blen -= 32;
00286 }
00287
00288 while(blen >=8)
00289 {
00290 cksum += w[0];
00291 cksum += w[1];
00292 cksum += w[2];
00293 cksum += w[3];
00294 w += 4;
00295 blen -= 8;
00296 }
00297
00298 while(blen > 1)
00299 {
00300 cksum += *w++;
00301 blen -= 2;
00302 }
00303
00304 if( blen == 1 )
00305 {
00306 *(unsigned char*)(&answer) = (*(unsigned char*)w);
00307 cksum += answer;
00308 }
00309
00310 cksum = (cksum >> 16) + (cksum & 0x0000ffff);
00311 cksum += (cksum >> 16);
00312
00313
00314 return (unsigned short)(~cksum);
00315 }
00316
00317 #endif