]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/capture/cap_debug/checksum.c
Merge branch 'stg-2.409-radius'
[stg.git] / projects / stargazer / plugins / capture / cap_debug / checksum.c
1 /*$Id: checksum.c,v 1.1 2005/12/12 18:14:22 nobunaga Exp $
2
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Lesser General Public
5 License as published by the Free Software Foundation; either
6 version 2.1 of the License, or (at your option) any later version.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Lesser General Public License for more details.
12
13 You should have received a copy of the GNU Lesser General Public
14 License along with this library; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18 unsigned short
19 in_cksum(unsigned short *addr, int len)
20 {
21         int                             nleft = len;
22         int                             sum = 0;
23         unsigned short  *w = addr;
24         unsigned short  answer = 0;
25
26         /*
27          * Our algorithm is simple, using a 32 bit accumulator (sum), we add
28          * sequential 16 bit words to it, and at the end, fold back all the
29          * carry bits from the top 16 bits into the lower 16 bits.
30          */
31         while (nleft > 1)  {
32                 sum += *w++;
33                 nleft -= 2;
34         }
35
36                 /* mop up an odd byte, if necessary */
37         if (nleft == 1) {
38                 *(unsigned char *)(&answer) = *(unsigned char *)w ;
39                 sum += answer;
40         }
41
42                 /* add back carry outs from top 16 bits to low 16 bits */
43         sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
44         sum += (sum >> 16);                     /* add carry */
45         answer = ~sum;                          /* truncate to 16 bits */
46         return(answer);
47 }