]> git.proxmox.com Git - mirror_frr.git/blame - isisd/iso_checksum.c
Indentation only. No any functional changes.
[mirror_frr.git] / isisd / iso_checksum.c
CommitLineData
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
45 * FIXME: Check for overflow
46 */
47
48int
f390d2c7 49iso_csum_verify (u_char * buffer, int len, uint16_t * csum)
50{
eb5d44eb 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;
f390d2c7 73
eb5d44eb 74 /*
75 * Otherwise initialize to zero and calculate...
76 */
77 c0 = 0;
78 c1 = 0;
79
f390d2c7 80 for (i = 0; i < len; i++)
81 {
82 c0 = c0 + *(p++);
83 c1 += c0;
84 }
eb5d44eb 85
86 c0 = c0 % 255;
87 c1 = c1 % 255;
f390d2c7 88
89 if (c0 == 0 && c1 == 0)
eb5d44eb 90 return 0;
91
92 return 1;
93}
94
eb5d44eb 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
f390d2c7 105iso_csum_create (u_char * buffer, int len, u_int16_t n)
eb5d44eb 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;
f390d2c7 115 u_int16_t *csum;
eb5d44eb 116 int i;
117
118 checksum = 0;
119
120 /*
121 * Zero the csum in the packet.
122 */
f390d2c7 123 csum = (u_int16_t *) (buffer + n);
eb5d44eb 124 *(csum) = checksum;
125
126 /* for the limitation of our implementation */
f390d2c7 127 if (len > 5000)
128 {
129 return 0;
130 }
eb5d44eb 131
132 p = buffer;
133 c0 = 0;
134 c1 = 0;
135
f390d2c7 136 for (i = 0; i < len; i++)
137 {
138 c0 = c0 + *(p++);
139 c1 += c0;
140 }
eb5d44eb 141
142 c0 = c0 % 255;
143 c1 = c1 % 255;
144
f390d2c7 145 mul = (len - n) * (c0);
146
eb5d44eb 147#ifdef FIXED_CODE
148 x = mul - c0 - c1;
149 y = c1 - mul - 1;
150
f390d2c7 151 if (y >= 0)
152 y++;
153 if (x < 0)
154 x--;
eb5d44eb 155
156 x %= 255;
157 y %= 255;
158
f390d2c7 159 if (x == 0)
160 x = 255;
161 if (y == 0)
162 y = 255;
eb5d44eb 163
164 x &= 0x00FF;
165
166 checksum = ((y << 8) | x);
167
168#else
169 x = mul - c0 - c1;
170 x %= 255;
171
172 y = c1 - mul - 1;
173 y %= 255;
174
f390d2c7 175 if (x == 0)
176 x = 255;
177 if (y == 0)
178 y = 255;
eb5d44eb 179
180 checksum = ((y << 8) | x);
181#endif
f390d2c7 182
eb5d44eb 183 /*
184 * Now we write this to the packet
185 */
186 *(csum) = checksum;
187
188 /* return the checksum for user usage */
189 return checksum;
190}
191
eb5d44eb 192int
f390d2c7 193iso_csum_modify (u_char * buffer, int len, uint16_t * csum)
eb5d44eb 194{
eb5d44eb 195 return 0;
196}