1 diff -ur quagga-0.99.8/ChangeLog quagga-unified-checksum/ChangeLog |
|
2 --- ChangeLog |
|
3 +++ ChangeLog |
|
4 @@ -1,3 +1,18 @@ |
|
5 +2008-06-25 Jingjing Duan <[email protected]> |
|
6 + * lib/checksum.[ch]: Add a consolidated checksum function to be |
|
7 + used by both OSPF and IS-IS. The consolidated version also fixes |
|
8 + the checksum byte-order checksum on big-endian architectures. |
|
9 + * isisd/iso_checksum.[ch]: Remove the old checksum implementation |
|
10 + and use the consolidated version. |
|
11 + * isisd/isis_dlpi.c: Change ioctl from PFIOCSETF (transparent mode) |
|
12 + to I_STR (non-transparent mode). The old code resulted in no |
|
13 + filtering at all. |
|
14 + * isisd/isis_dlpi.c: (open_dlpi_dev) Clearview-UV device nodes are |
|
15 + under /dev/net, try opening there before attempting style 1 or 2 |
|
16 + names. |
|
17 + * ospfd/ospf_lsa.c: Remove the old checksum implementation and |
|
18 + use the consolidated version. |
|
19 + |
|
20 2007-08-07 James Carlson <[email protected]> |
|
21 |
|
22 * configure.ac: Added support for separate link-layer access |
|
23 diff -ur quagga-0.99.8/isisd/isis_dlpi.c quagga-unified-checksum/isisd/isis_dlpi.c |
|
24 --- isisd/isis_dlpi.c |
|
25 +++ isisd/isis_dlpi.c |
|
26 @@ -42,8 +42,6 @@ |
|
27 #include "isisd/isis_circuit.h" |
|
28 #include "isisd/isis_flags.h" |
|
29 #include "isisd/isisd.h" |
|
30 -#include "isisd/isis_constants.h" |
|
31 -#include "isisd/isis_circuit.h" |
|
32 #include "isisd/isis_network.h" |
|
33 |
|
34 #include "privs.h" |
|
35 @@ -315,13 +313,24 @@ |
|
36 circuit->interface->name); |
|
37 return ISIS_WARNING; |
|
38 } |
|
39 + |
|
40 + /* Try the vanity node first, if permitted */ |
|
41 + if (getenv("DLPI_DEVONLY") == NULL) |
|
42 + { |
|
43 + (void) snprintf (devpath, sizeof(devpath), "/dev/net/%s", |
|
44 + circuit->interface->name); |
|
45 + fd = dlpiopen (devpath, &acklen); |
|
46 + } |
|
47 + |
|
48 + /* Now try as an ordinary Style 1 node */ |
|
49 + if (fd == -1) |
|
50 + { |
|
51 + (void) snprintf (devpath, sizeof (devpath), "/dev/%s", |
|
52 + circuit->interface->name); |
|
53 + unit = -1; |
|
54 + fd = dlpiopen (devpath, &acklen); |
|
55 + } |
|
56 |
|
57 - /* Try first as Style 1 */ |
|
58 - (void) snprintf(devpath, sizeof (devpath), "/dev/%s", |
|
59 - circuit->interface->name); |
|
60 - unit = -1; |
|
61 - fd = dlpiopen (devpath, &acklen); |
|
62 - |
|
63 /* If that fails, try again as Style 2 */ |
|
64 if (fd == -1) |
|
65 { |
|
66 @@ -452,11 +461,19 @@ |
|
67 if (ioctl (fd, I_PUSH, "pfmod") == 0) |
|
68 { |
|
69 struct packetfilt pfil; |
|
70 + struct strioctl sioc; |
|
71 |
|
72 pfil.Pf_Priority = 0; |
|
73 pfil.Pf_FilterLen = sizeof (pf_filter) / sizeof (u_short); |
|
74 memcpy (pfil.Pf_Filter, pf_filter, sizeof (pf_filter)); |
|
75 - ioctl (fd, PFIOCSETF, &pfil); |
|
76 + /* pfmod does not support transparent ioctls */ |
|
77 + sioc.ic_cmd = PFIOCSETF; |
|
78 + sioc.ic_timout = 5; |
|
79 + sioc.ic_len = sizeof (struct packetfilt); |
|
80 + sioc.ic_dp = (char *)&pfil; |
|
81 + if (ioctl (fd, I_STR, &sioc) == -1) |
|
82 + zlog_warn("%s: could not perform PF_IOCSETF on %s", |
|
83 + __func__, circuit->interface->name); |
|
84 } |
|
85 |
|
86 circuit->fd = fd; |
|
87 diff -ur quagga-0.99.8/isisd/isis_lsp.c quagga-unified-checksum/isisd/isis_lsp.c |
|
88 --- isisd/isis_lsp.c |
|
89 +++ isisd/isis_lsp.c |
|
90 @@ -33,6 +33,7 @@ |
|
91 #include "command.h" |
|
92 #include "hash.h" |
|
93 #include "if.h" |
|
94 +#include "checksum.h" |
|
95 |
|
96 #include "isisd/dict.h" |
|
97 #include "isisd/isis_constants.h" |
|
98 @@ -45,7 +46,6 @@ |
|
99 #include "isisd/isis_dynhn.h" |
|
100 #include "isisd/isis_misc.h" |
|
101 #include "isisd/isis_flags.h" |
|
102 -#include "isisd/iso_checksum.h" |
|
103 #include "isisd/isis_csm.h" |
|
104 #include "isisd/isis_adjacency.h" |
|
105 #include "isisd/isis_spf.h" |
|
106 @@ -314,7 +314,7 @@ |
|
107 newseq = seq_num++; |
|
108 |
|
109 lsp->lsp_header->seq_num = htonl (newseq); |
|
110 - iso_csum_create (STREAM_DATA (lsp->pdu) + 12, |
|
111 + fletcher_checksum (STREAM_DATA (lsp->pdu) + 12, |
|
112 ntohs (lsp->lsp_header->pdu_len) - 12, 12); |
|
113 |
|
114 return; |
|
115 @@ -1803,7 +1803,7 @@ |
|
116 tlv_add_is_neighs (lsp->tlv_data.es_neighs, lsp->pdu); |
|
117 |
|
118 lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu)); |
|
119 - iso_csum_create (STREAM_DATA (lsp->pdu) + 12, |
|
120 + fletcher_checksum (STREAM_DATA (lsp->pdu) + 12, |
|
121 ntohs (lsp->lsp_header->pdu_len) - 12, 12); |
|
122 |
|
123 list_delete (adj_list); |
|
124 @@ -2071,7 +2071,7 @@ |
|
125 lsp->lsp_header->pdu_len = |
|
126 htons (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN); |
|
127 lsp->purged = 0; |
|
128 - iso_csum_create (STREAM_DATA (lsp->pdu) + 12, |
|
129 + fletcher_checksum (STREAM_DATA (lsp->pdu) + 12, |
|
130 ntohs (lsp->lsp_header->pdu_len) - 12, 12); |
|
131 ISIS_FLAGS_SET_ALL (lsp->SRMflags); |
|
132 } |
|
133 diff -ur quagga-0.99.8/isisd/isis_pdu.c quagga-unified-checksum/isisd/isis_pdu.c |
|
134 --- isisd/isis_pdu.c |
|
135 +++ isisd/isis_pdu.c |
|
136 @@ -32,6 +32,7 @@ |
|
137 #include "hash.c" |
|
138 #include "prefix.h" |
|
139 #include "if.h" |
|
140 +#include "checksum.h" |
|
141 |
|
142 #include "isisd/dict.h" |
|
143 #include "isisd/include-netbsd/iso.h" |
|
144 @@ -1121,7 +1122,7 @@ |
|
145 if (isis->debugs & DEBUG_UPDATE_PACKETS) |
|
146 zlog_debug ("LSP LEN: %d", |
|
147 ntohs (lsp->lsp_header->pdu_len)); |
|
148 - iso_csum_create (STREAM_DATA (lsp->pdu) + 12, |
|
149 + fletcher_checksum (STREAM_DATA (lsp->pdu) + 12, |
|
150 ntohs (lsp->lsp_header->pdu_len) - 12, 12); |
|
151 ISIS_FLAGS_SET_ALL (lsp->SRMflags); |
|
152 if (isis->debugs & DEBUG_UPDATE_PACKETS) |
|
153 @@ -1164,7 +1165,7 @@ |
|
154 /* 7.3.16.1 */ |
|
155 lsp->lsp_header->seq_num = htonl (ntohl (hdr->seq_num) + 1); |
|
156 |
|
157 - iso_csum_create (STREAM_DATA (lsp->pdu) + 12, |
|
158 + fletcher_checksum (STREAM_DATA (lsp->pdu) + 12, |
|
159 ntohs (lsp->lsp_header->pdu_len) - 12, 12); |
|
160 |
|
161 ISIS_FLAGS_SET_ALL (lsp->SRMflags); |
|
162 diff -ur quagga-0.99.8/isisd/iso_checksum.c quagga-unified-checksum/isisd/iso_checksum.c |
|
163 --- isisd/iso_checksum.c |
|
164 +++ isisd/iso_checksum.c |
|
165 @@ -23,6 +23,7 @@ |
|
166 |
|
167 #include <zebra.h> |
|
168 #include "iso_checksum.h" |
|
169 +#include "checksum.h" |
|
170 |
|
171 /* |
|
172 * Calculations of the OSI checksum. |
|
173 @@ -47,14 +48,10 @@ |
|
174 int |
|
175 iso_csum_verify (u_char * buffer, int len, uint16_t * csum) |
|
176 { |
|
177 - u_int8_t *p; |
|
178 + u_int16_t checksum; |
|
179 u_int32_t c0; |
|
180 u_int32_t c1; |
|
181 - u_int16_t checksum; |
|
182 - int i, partial_len; |
|
183 |
|
184 - p = buffer; |
|
185 - checksum = 0; |
|
186 c0 = *csum & 0xff00; |
|
187 c1 = *csum & 0x00ff; |
|
188 |
|
189 @@ -70,124 +69,8 @@ |
|
190 if (c0 == 0 || c1 == 0) |
|
191 return 1; |
|
192 |
|
193 - /* |
|
194 - * Otherwise initialize to zero and calculate... |
|
195 - */ |
|
196 - c0 = 0; |
|
197 - c1 = 0; |
|
198 - |
|
199 - while (len) |
|
200 - { |
|
201 - partial_len = MIN(len, 5803); |
|
202 - |
|
203 - for (i = 0; i < partial_len; i++) |
|
204 - { |
|
205 - c0 = c0 + *(p++); |
|
206 - c1 += c0; |
|
207 - } |
|
208 - |
|
209 - c0 = c0 % 255; |
|
210 - c1 = c1 % 255; |
|
211 - |
|
212 - len -= partial_len; |
|
213 - } |
|
214 - |
|
215 - if (c0 == 0 && c1 == 0) |
|
216 - return 0; |
|
217 - |
|
218 + checksum = fletcher_checksum(buffer, len, (u_char *)csum - buffer); |
|
219 + if (checksum == *csum) |
|
220 + return 0; |
|
221 return 1; |
|
222 } |
|
223 - |
|
224 -/* |
|
225 - * Creates the checksum. *csum points to the position of the checksum in the |
|
226 - * PDU. |
|
227 - * Based on Annex C.4 of ISO/IEC 8473 |
|
228 - */ |
|
229 -#define FIXED_CODE |
|
230 -u_int16_t |
|
231 -iso_csum_create (u_char * buffer, int len, u_int16_t n) |
|
232 -{ |
|
233 - |
|
234 - u_int8_t *p; |
|
235 - int x; |
|
236 - int y; |
|
237 - u_int32_t mul; |
|
238 - u_int32_t c0; |
|
239 - u_int32_t c1; |
|
240 - u_int16_t checksum; |
|
241 - u_int16_t *csum; |
|
242 - int i, init_len, partial_len; |
|
243 - |
|
244 - checksum = 0; |
|
245 - |
|
246 - /* |
|
247 - * Zero the csum in the packet. |
|
248 - */ |
|
249 - csum = (u_int16_t *) (buffer + n); |
|
250 - *(csum) = checksum; |
|
251 - |
|
252 - p = buffer; |
|
253 - c0 = 0; |
|
254 - c1 = 0; |
|
255 - init_len = len; |
|
256 - |
|
257 - while (len != 0) |
|
258 - { |
|
259 - partial_len = MIN(len, 5803); |
|
260 - |
|
261 - for (i = 0; i < partial_len; i++) |
|
262 - { |
|
263 - c0 = c0 + *(p++); |
|
264 - c1 += c0; |
|
265 - } |
|
266 - |
|
267 - c0 = c0 % 255; |
|
268 - c1 = c1 % 255; |
|
269 - |
|
270 - len -= partial_len; |
|
271 - } |
|
272 - |
|
273 - mul = (init_len - n)*(c0); |
|
274 - |
|
275 -#ifdef FIXED_CODE |
|
276 - x = mul - c0 - c1; |
|
277 - y = c1 - mul - 1; |
|
278 - |
|
279 - if (y > 0) |
|
280 - y++; |
|
281 - if (x < 0) |
|
282 - x--; |
|
283 - |
|
284 - x %= 255; |
|
285 - y %= 255; |
|
286 - |
|
287 - if (x == 0) |
|
288 - x = 255; |
|
289 - if (y == 0) |
|
290 - y = 1; |
|
291 - |
|
292 - checksum = (y << 8) | (x & 0xFF); |
|
293 - |
|
294 -#else |
|
295 - x = mul - c0 - c1; |
|
296 - x %= 255; |
|
297 - |
|
298 - y = c1 - mul - 1; |
|
299 - y %= 255; |
|
300 - |
|
301 - if (x == 0) |
|
302 - x = 255; |
|
303 - if (y == 0) |
|
304 - y = 255; |
|
305 - |
|
306 - checksum = ((y << 8) | x); |
|
307 -#endif |
|
308 - |
|
309 - /* |
|
310 - * Now we write this to the packet |
|
311 - */ |
|
312 - *(csum) = checksum; |
|
313 - |
|
314 - /* return the checksum for user usage */ |
|
315 - return checksum; |
|
316 -} |
|
317 diff -ur quagga-0.99.8/isisd/iso_checksum.h quagga-unified-checksum/isisd/iso_checksum.h |
|
318 --- isisd/iso_checksum.h |
|
319 +++ isisd/iso_checksum.h |
|
320 @@ -24,6 +24,5 @@ |
|
321 #define _ZEBRA_ISO_CSUM_H |
|
322 |
|
323 int iso_csum_verify (u_char * buffer, int len, uint16_t * csum); |
|
324 -u_int16_t iso_csum_create (u_char * buffer, int len, u_int16_t n); |
|
325 |
|
326 #endif /* _ZEBRA_ISO_CSUM_H */ |
|
327 diff -ur quagga-0.99.8/lib/checksum.c quagga-unified-checksum/lib/checksum.c |
|
328 --- lib/checksum.c |
|
329 +++ lib/checksum.c |
|
330 @@ -45,3 +45,82 @@ |
|
331 answer = ~sum; /* ones-complement, then truncate to 16 bits */ |
|
332 return(answer); |
|
333 } |
|
334 + |
|
335 +/* Fletcher Checksum -- Refer to RFC1008. */ |
|
336 +#define MODX 4102 /* 5802 should be fine */ |
|
337 + |
|
338 +/* To be consistent, offset is 0-based index, rather than the 1-based |
|
339 + index required in the specification ISO 8473, Annex C.1 */ |
|
340 +u_int16_t |
|
341 +fletcher_checksum(u_char * buffer, int len, u_int16_t offset) |
|
342 +{ |
|
343 + u_int8_t *p; |
|
344 + int x; |
|
345 + int y; |
|
346 + u_int32_t mul; |
|
347 + u_int32_t c0; |
|
348 + u_int32_t c1; |
|
349 + u_int16_t checksum; |
|
350 + u_int16_t *csum; |
|
351 + int i, init_len, partial_len; |
|
352 + |
|
353 + checksum = 0; |
|
354 + |
|
355 + /* |
|
356 + * Zero the csum in the packet. |
|
357 + */ |
|
358 + csum = (u_int16_t *) (buffer + offset); |
|
359 + *(csum) = checksum; |
|
360 + |
|
361 + p = buffer; |
|
362 + c0 = 0; |
|
363 + c1 = 0; |
|
364 + init_len = len; |
|
365 + |
|
366 + while (len != 0) |
|
367 + { |
|
368 + partial_len = MIN(len, MODX); |
|
369 + |
|
370 + for (i = 0; i < partial_len; i++) |
|
371 + { |
|
372 + c0 = c0 + *(p++); |
|
373 + c1 += c0; |
|
374 + } |
|
375 + |
|
376 + c0 = c0 % 255; |
|
377 + c1 = c1 % 255; |
|
378 + |
|
379 + len -= partial_len; |
|
380 + } |
|
381 + |
|
382 + mul = (init_len - offset)*(c0); |
|
383 + |
|
384 + x = mul - c0 - c1; |
|
385 + y = c1 - mul - 1; |
|
386 + |
|
387 + if (y > 0) |
|
388 + y++; |
|
389 + if (x < 0) |
|
390 + x--; |
|
391 + |
|
392 + x %= 255; |
|
393 + y %= 255; |
|
394 + |
|
395 + if (x == 0) |
|
396 + x = 255; |
|
397 + if (y == 0) |
|
398 + y = 1; |
|
399 + |
|
400 + /* |
|
401 + * Now we write this to the packet. |
|
402 + * We could skip this step too, since the checksum returned would |
|
403 + * be stored into the checksum field by the caller. |
|
404 + */ |
|
405 + buffer[offset] = x; |
|
406 + buffer[offset + 1] = y; |
|
407 + |
|
408 + /* Take care of the endian issue */ |
|
409 + checksum = htons((x << 8) | (y & 0xFF)); |
|
410 + |
|
411 + return checksum; |
|
412 +} |
|
413 diff -ur quagga-0.99.8/lib/checksum.h quagga-unified-checksum/lib/checksum.h |
|
414 --- lib/checksum.h |
|
415 +++ lib/checksum.h |
|
416 @@ -1 +1,2 @@ |
|
417 extern int in_cksum(void *, int); |
|
418 +extern u_int16_t fletcher_checksum(u_char * buffer, int len, u_int16_t offset); |
|
419 diff -ur quagga-0.99.8/ospfd/ospf_lsa.c quagga-unified-checksum/ospfd/ospf_lsa.c |
|
420 --- ospfd/ospf_lsa.c |
|
421 +++ ospfd/ospf_lsa.c |
|
422 @@ -32,6 +32,7 @@ |
|
423 #include "thread.h" |
|
424 #include "hash.h" |
|
425 #include "sockunion.h" /* for inet_aton() */ |
|
426 +#include "checksum.h" |
|
427 |
|
428 #include "ospfd/ospfd.h" |
|
429 #include "ospfd/ospf_interface.h" |
|
430 @@ -172,46 +173,22 @@ |
|
431 |
|
432 |
|
433 /* Fletcher Checksum -- Refer to RFC1008. */ |
|
434 -#define MODX 4102 |
|
435 -#define LSA_CHECKSUM_OFFSET 15 |
|
436 |
|
437 +/* All the offsets are zero-based. The offsets in the RFC1008 are |
|
438 + one-based. */ |
|
439 u_int16_t |
|
440 ospf_lsa_checksum (struct lsa_header *lsa) |
|
441 { |
|
442 - u_char *sp, *ep, *p, *q; |
|
443 - int c0 = 0, c1 = 0; |
|
444 - int x, y; |
|
445 - u_int16_t length; |
|
446 - |
|
447 - lsa->checksum = 0; |
|
448 - length = ntohs (lsa->length) - 2; |
|
449 - sp = (u_char *) &lsa->options; |
|
450 - |
|
451 - for (ep = sp + length; sp < ep; sp = q) |
|
452 - { |
|
453 - q = sp + MODX; |
|
454 - if (q > ep) |
|
455 - q = ep; |
|
456 - for (p = sp; p < q; p++) |
|
457 - { |
|
458 - c0 += *p; |
|
459 - c1 += c0; |
|
460 - } |
|
461 - c0 %= 255; |
|
462 - c1 %= 255; |
|
463 - } |
|
464 + u_char *buffer = (u_char *) &lsa->options; |
|
465 + int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */ |
|
466 |
|
467 - x = (((int)length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255; |
|
468 - if (x <= 0) |
|
469 - x += 255; |
|
470 - y = 510 - c0 - x; |
|
471 - if (y > 255) |
|
472 - y -= 255; |
|
473 + /* Skip the AGE field */ |
|
474 + u_int16_t len = ntohs(lsa->length) - options_offset; |
|
475 |
|
476 - /* take care endian issue. */ |
|
477 - lsa->checksum = htons ((x << 8) + y); |
|
478 + /* Checksum offset starts from "options" field, not the beginning of the |
|
479 + lsa_header struct. The offset is 14, rather than 16. */ |
|
480 |
|
481 - return (lsa->checksum); |
|
482 + return fletcher_checksum(buffer, len, (u_char *) &lsa->checksum - buffer); |
|
483 } |
|
484 |
|
485 |
|
486 diff -ur quagga-0.99.8/solaris/quagga.init.in quagga-unified-checksum/solaris/quagga.init.in |
1 diff -ur quagga-0.99.8/solaris/quagga.init.in quagga-unified-checksum/solaris/quagga.init.in |
487 --- solaris/quagga.init.in |
2 --- solaris/quagga.init.in |
488 +++ solaris/quagga.init.in |
3 +++ solaris/quagga.init.in |
489 @@ -134,7 +134,7 @@ |
4 @@ -134,7 +134,7 @@ |
490 case "${DAEMON}" in |
5 case "${DAEMON}" in |