+ note the meta-queue in NEWS
[jleu-quagga.git] / isisd / iso_checksum.c
blob16f18e50a3dcb936a0cf9db950c6d8f7229eea98
1 /*
2 * IS-IS Rout(e)ing protocol - iso_checksum.c
3 * ISO checksum related routines
5 * Copyright (C) 2001,2002 Sampo Saaristo
6 * Tampere University of Technology
7 * Institute of Communications Engineering
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public Licenseas published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
14 * This program is distributed in the hope that it will be useful,but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <zebra.h>
25 #include "iso_checksum.h"
28 * Calculations of the OSI checksum.
29 * ISO/IEC 8473 defines the sum as
31 * L
32 * sum a (mod 255) = 0
33 * 1 i
35 * L
36 * sum (L-i+1)a (mod 255) = 0
37 * 1 i
42 * Verifies that the checksum is correct.
43 * Return 0 on correct and 1 on invalid checksum.
44 * Based on Annex C.4 of ISO/IEC 8473
47 int
48 iso_csum_verify (u_char * buffer, int len, uint16_t * csum)
50 u_int8_t *p;
51 u_int32_t c0;
52 u_int32_t c1;
53 u_int16_t checksum;
54 int i, partial_len;
56 p = buffer;
57 checksum = 0;
58 c0 = *csum & 0xff00;
59 c1 = *csum & 0x00ff;
62 * If both are zero return correct
64 if (c0 == 0 && c1 == 0)
65 return 0;
68 * If either, but not both are zero return incorrect
70 if (c0 == 0 || c1 == 0)
71 return 1;
74 * Otherwise initialize to zero and calculate...
76 c0 = 0;
77 c1 = 0;
79 while (len)
81 partial_len = MIN(len, 5803);
83 for (i = 0; i < partial_len; i++)
85 c0 = c0 + *(p++);
86 c1 += c0;
89 c0 = c0 % 255;
90 c1 = c1 % 255;
92 len -= partial_len;
95 if (c0 == 0 && c1 == 0)
96 return 0;
98 return 1;
102 * Creates the checksum. *csum points to the position of the checksum in the
103 * PDU.
104 * Based on Annex C.4 of ISO/IEC 8473
106 #define FIXED_CODE
107 u_int16_t
108 iso_csum_create (u_char * buffer, int len, u_int16_t n)
111 u_int8_t *p;
112 int x;
113 int y;
114 u_int32_t mul;
115 u_int32_t c0;
116 u_int32_t c1;
117 u_int16_t checksum;
118 u_int16_t *csum;
119 int i, init_len, partial_len;
121 checksum = 0;
124 * Zero the csum in the packet.
126 csum = (u_int16_t *) (buffer + n);
127 *(csum) = checksum;
129 p = buffer;
130 c0 = 0;
131 c1 = 0;
132 init_len = len;
134 while (len != 0)
136 partial_len = MIN(len, 5803);
138 for (i = 0; i < partial_len; i++)
140 c0 = c0 + *(p++);
141 c1 += c0;
144 c0 = c0 % 255;
145 c1 = c1 % 255;
147 len -= partial_len;
150 mul = (init_len - n)*(c0);
152 #ifdef FIXED_CODE
153 x = mul - c0 - c1;
154 y = c1 - mul - 1;
156 if (y > 0)
157 y++;
158 if (x < 0)
159 x--;
161 x %= 255;
162 y %= 255;
164 if (x == 0)
165 x = 255;
166 if (y == 0)
167 y = 1;
169 checksum = (y << 8) | (x & 0xFF);
171 #else
172 x = mul - c0 - c1;
173 x %= 255;
175 y = c1 - mul - 1;
176 y %= 255;
178 if (x == 0)
179 x = 255;
180 if (y == 0)
181 y = 255;
183 checksum = ((y << 8) | x);
184 #endif
187 * Now we write this to the packet
189 *(csum) = checksum;
191 /* return the checksum for user usage */
192 return checksum;