blob: d0bb8a75d58fc96943baacebd0ca0d566c34cec9 [file] [log] [blame]
jardineb5d44e2003-12-23 08:09:43 +00001/*
2 * IS-IS Rout(e)ing protocol - iso_checksum.c
3 * ISO checksum related routines
4 *
5 * Copyright (C) 2001,2002 Sampo Saaristo
6 * Tampere University of Technology
7 * Institute of Communications Engineering
8 *
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.
13 *
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.
18
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.
22 */
23
24#include <zebra.h>
25#include "iso_checksum.h"
26
27/*
28 * Calculations of the OSI checksum.
29 * ISO/IEC 8473 defines the sum as
30 *
31 * L
32 * sum a (mod 255) = 0
33 * 1 i
34 *
35 * L
36 * sum (L-i+1)a (mod 255) = 0
37 * 1 i
38 *
39 */
40
41/*
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
45 * FIXME: Check for overflow
46 */
47
48int
49iso_csum_verify (u_char *buffer, int len, uint16_t *csum)
50{
51 u_int8_t *p;
52 u_int32_t c0;
53 u_int32_t c1;
54 u_int16_t checksum;
55 int i;
56
57 p = buffer;
58 checksum = 0;
59 c0 = *csum & 0xff00;
60 c1 = *csum & 0x00ff;
61
62 /*
63 * If both are zero return correct
64 */
65 if (c0 == 0 && c1 == 0)
66 return 0;
67
68 /*
69 * If either, but not both are zero return incorrect
70 */
71 if (c0 == 0 || c1 == 0)
72 return 1;
73
74 /*
75 * Otherwise initialize to zero and calculate...
76 */
77 c0 = 0;
78 c1 = 0;
79
80 for (i = 0; i < len; i++) {
81 c0 = c0 + *(p++);
82 c1 += c0;
83 }
84
85 c0 = c0 % 255;
86 c1 = c1 % 255;
87
88 if ( c0 == 0 && c1 == 0)
89 return 0;
90
91 return 1;
92}
93
94
95/*
96 * Creates the checksum. *csum points to the position of the checksum in the
97 * PDU.
98 * Based on Annex C.4 of ISO/IEC 8473
99 * we will not overflow until about length of 6000,
100 * which is the answer to (255+255n)*n/2 > 2^32
101 * so if we have a length of over 5000 we will return zero (for now)
102 */
103#define FIXED_CODE
104u_int16_t
105iso_csum_create (u_char *buffer, int len, u_int16_t n)
106{
107
108 u_int8_t *p;
109 int x;
110 int y;
111 u_int32_t mul;
112 u_int32_t c0;
113 u_int32_t c1;
114 u_int16_t checksum;
115 u_int16_t *csum;
116 int i;
117
118 checksum = 0;
119
120 /*
121 * Zero the csum in the packet.
122 */
123 csum = (u_int16_t*)(buffer + n);
124 *(csum) = checksum;
125
126 /* for the limitation of our implementation */
127 if (len > 5000) {
128 return 0;
129 }
130
131 p = buffer;
132 c0 = 0;
133 c1 = 0;
134
135 for (i = 0; i < len; i++) {
136 c0 = c0 + *(p++);
137 c1 += c0;
138 }
139
140 c0 = c0 % 255;
141 c1 = c1 % 255;
142
143 mul = (len - n)*(c0);
144
145#ifdef FIXED_CODE
146 x = mul - c0 - c1;
147 y = c1 - mul - 1;
148
149 if ( y >= 0 ) y++;
150 if ( x < 0 ) x--;
151
152 x %= 255;
153 y %= 255;
154
155 if (x == 0) x = 255;
156 if (y == 0) y = 255;
157
158 x &= 0x00FF;
159
160 checksum = ((y << 8) | x);
161
162#else
163 x = mul - c0 - c1;
164 x %= 255;
165
166 y = c1 - mul - 1;
167 y %= 255;
168
169 if (x == 0) x = 255;
170 if (y == 0) y = 255;
171
172 checksum = ((y << 8) | x);
173#endif
174
175 /*
176 * Now we write this to the packet
177 */
178 *(csum) = checksum;
179
180 /* return the checksum for user usage */
181 return checksum;
182}
183
184
185int
186iso_csum_modify (u_char *buffer, int len, uint16_t *csum)
187{
188
189 return 0;
190}
191
192