]>
Commit | Line | Data |
---|---|---|
eb5d44eb | 1 | /* |
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 | |
eb5d44eb | 45 | */ |
46 | ||
47 | int | |
f390d2c7 | 48 | iso_csum_verify (u_char * buffer, int len, uint16_t * csum) |
49 | { | |
eb5d44eb | 50 | u_int8_t *p; |
51 | u_int32_t c0; | |
52 | u_int32_t c1; | |
53 | u_int16_t checksum; | |
53c997c9 | 54 | int i, partial_len; |
eb5d44eb | 55 | |
56 | p = buffer; | |
57 | checksum = 0; | |
58 | c0 = *csum & 0xff00; | |
59 | c1 = *csum & 0x00ff; | |
60 | ||
61 | /* | |
62 | * If both are zero return correct | |
63 | */ | |
64 | if (c0 == 0 && c1 == 0) | |
65 | return 0; | |
66 | ||
67 | /* | |
68 | * If either, but not both are zero return incorrect | |
69 | */ | |
70 | if (c0 == 0 || c1 == 0) | |
71 | return 1; | |
f390d2c7 | 72 | |
eb5d44eb | 73 | /* |
74 | * Otherwise initialize to zero and calculate... | |
75 | */ | |
76 | c0 = 0; | |
77 | c1 = 0; | |
78 | ||
53c997c9 | 79 | while (len) |
f390d2c7 | 80 | { |
53c997c9 | 81 | partial_len = MIN(len, 5803); |
82 | ||
83 | for (i = 0; i < partial_len; i++) | |
84 | { | |
85 | c0 = c0 + *(p++); | |
86 | c1 += c0; | |
87 | } | |
eb5d44eb | 88 | |
53c997c9 | 89 | c0 = c0 % 255; |
90 | c1 = c1 % 255; | |
91 | ||
92 | len -= partial_len; | |
93 | } | |
f390d2c7 | 94 | |
95 | if (c0 == 0 && c1 == 0) | |
eb5d44eb | 96 | return 0; |
97 | ||
98 | return 1; | |
99 | } | |
100 | ||
eb5d44eb | 101 | /* |
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 | |
eb5d44eb | 105 | */ |
106 | #define FIXED_CODE | |
107 | u_int16_t | |
f390d2c7 | 108 | iso_csum_create (u_char * buffer, int len, u_int16_t n) |
eb5d44eb | 109 | { |
110 | ||
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; | |
f390d2c7 | 118 | u_int16_t *csum; |
53c997c9 | 119 | int i, init_len, partial_len; |
eb5d44eb | 120 | |
121 | checksum = 0; | |
122 | ||
123 | /* | |
124 | * Zero the csum in the packet. | |
125 | */ | |
f390d2c7 | 126 | csum = (u_int16_t *) (buffer + n); |
eb5d44eb | 127 | *(csum) = checksum; |
128 | ||
eb5d44eb | 129 | p = buffer; |
130 | c0 = 0; | |
131 | c1 = 0; | |
53c997c9 | 132 | init_len = len; |
eb5d44eb | 133 | |
53c997c9 | 134 | while (len != 0) |
f390d2c7 | 135 | { |
53c997c9 | 136 | partial_len = MIN(len, 5803); |
137 | ||
138 | for (i = 0; i < partial_len; i++) | |
139 | { | |
140 | c0 = c0 + *(p++); | |
141 | c1 += c0; | |
142 | } | |
eb5d44eb | 143 | |
53c997c9 | 144 | c0 = c0 % 255; |
145 | c1 = c1 % 255; | |
146 | ||
147 | len -= partial_len; | |
148 | } | |
eb5d44eb | 149 | |
53c997c9 | 150 | mul = (init_len - n)*(c0); |
f390d2c7 | 151 | |
eb5d44eb | 152 | #ifdef FIXED_CODE |
153 | x = mul - c0 - c1; | |
154 | y = c1 - mul - 1; | |
155 | ||
53c997c9 | 156 | if (y > 0) |
f390d2c7 | 157 | y++; |
158 | if (x < 0) | |
159 | x--; | |
eb5d44eb | 160 | |
161 | x %= 255; | |
162 | y %= 255; | |
163 | ||
f390d2c7 | 164 | if (x == 0) |
165 | x = 255; | |
166 | if (y == 0) | |
53c997c9 | 167 | y = 1; |
eb5d44eb | 168 | |
53c997c9 | 169 | checksum = (y << 8) | (x & 0xFF); |
eb5d44eb | 170 | |
171 | #else | |
172 | x = mul - c0 - c1; | |
173 | x %= 255; | |
174 | ||
175 | y = c1 - mul - 1; | |
176 | y %= 255; | |
177 | ||
f390d2c7 | 178 | if (x == 0) |
179 | x = 255; | |
180 | if (y == 0) | |
181 | y = 255; | |
eb5d44eb | 182 | |
183 | checksum = ((y << 8) | x); | |
184 | #endif | |
f390d2c7 | 185 | |
eb5d44eb | 186 | /* |
187 | * Now we write this to the packet | |
188 | */ | |
189 | *(csum) = checksum; | |
190 | ||
191 | /* return the checksum for user usage */ | |
192 | return checksum; | |
193 | } | |
194 | ||
eb5d44eb | 195 | int |
f390d2c7 | 196 | iso_csum_modify (u_char * buffer, int len, uint16_t * csum) |
eb5d44eb | 197 | { |
eb5d44eb | 198 | return 0; |
199 | } |