summaryrefslogtreecommitdiff
path: root/lib/checksum.h
AgeCommit message (Collapse)Author
2012-10-25lib: improve fletcher checksum validationJR Rivers
OVERVIEW The checksum used in OSPF (rfc2328) is specified in rc905 annex B. There is an sample implementation in rfc1008 which forms the basis of the quagga implementation. This algorithm works perfectly when generating a checksum; however, validation is a bit problematic. The following LSA (generated by a non-quagga implementation) is received by quagga and marked with an invalid checksum; however, it passes both the rfc905 and rfc1008 validation checks. static uint8_t lsa_10_121_233_29[] = { 0x0e, 0x10, 0x02, 0x03, 0x09, 0x00, 0x35, 0x40, 0x0a, 0x79, 0xe9, 0x1d, 0x80, 0x00, 0x00, 0x03, 0x00, 0x8a, 0x00, 0x1c, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x36, 0xb0 }; LS Type: Summary-LSA (IP network) LS Age: 3600 seconds Do Not Age: False Options: 0x02 (E) Link-State Advertisement Type: Summary-LSA (IP network) (3) Link State ID: 9.0.53.64 Advertising Router: 10.121.233.29 (10.121.233.29) LS Sequence Number: 0x80000003 LS Checksum: 0x008a Length: 28 Netmask: 255.255.255.224 Metric: 14000 You'll note that one byte of the checksum is 0x00; quagga would calculate the checksum as 0xff8a. It can be argued that the sourcing implementation generates an incorrect checksum; however, rfc905 indicates that, for 1's complement arithmetic, the value 255 shall be regarded as 0, thus either values are valid. EXPLANATION The quagga ospfd and ospf6d implementations operate by copying the PDU's existing checksum in a holding variable, calculating the checksum, and comparing the resulting checksum to the original. As a note, this implementation has the side effect of modifying the contents of the PDU. Evaluation of both rfc905 and rfc1008 shows that checksum validation should involve calculating the sum over the PDU and checking that both resulting C0 and C1 values are zero. This behavior is enacted in the rfc1008 implementation by calling encodecc with k = 0 (checksum offset); however, this functionality had been omitted from the quagga implementation. PATCH This patch adds the ability to call the quagga's fletcher_checksum() with a checksum offset value of 0xffff (aka FLETCHER_CHECKSUM_VALIDATE) which returns the sum over the buffer (a value of 0 indicates a valid checksum). This is similar to the mechanism in rfc1008 when called with k = 0. The patch also introduces ospf_lsa_checksum_valid(). ospf6d had it's own implementation of the fletcher checksum in ospf6_lsa_checksum(); it's the same algorithm as in fletcher_checksum(). This patch removes the local implementation in favor of the library's as well as creates and uses ospf6_lsa_checksum_valid(). quagga's ISIS implementation suffers from the same problem; however, I do not have the facilities to validate a fix to ISIS, thus this change has been left to the ISIS maintainers. The function iso_csum_verify() should be reduced to running the fletcher checksum over the buffer using an offset of 0. Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com> Reviewed-by: Scott Feldman <sfeldma@cumulusnetworks.com> Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com> Reviewed-by: Ayan Banerjee <ayan@cumulusnetworks.com> Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2008-11-16[lib] Switch Fletcher checksum back to old ospfd versionPaul Jakma
* lib/checksum.c: (fletcher_checksum) Switch the second phase of the checksum back to the old ospfd logic. The isisd-derived version: a) is very hard to follow b) had some kind of subtle bug that caused it be wrong when c0=0 and c1=254 (potentially fixable by doing the mods before adjusting x and y) Additionally: - explicitely cast expressions using non-internal variables to int, to ensure the result is signed. - defensively change the length argument to 'size_t', to ensure the code works with that argument being unsigned.. Thanks to Joakim Tjernlund for the investigative work into this bug. * tests/test-checksum.c: new file to exercise the checksum code.
2008-08-22[lib] Add fletcher checksum implementationJingjing Duan
2008-08-13 Jingjing Duan <Jingjing.Duan@sun.com> * lib/checksum.?: (fletcher_checksum) implementation of Fletcher checksum, as per RFC1008. Signed-off-by: Paul Jakma <paul@quagga.net>
2005-11-032005-11-03 Paul Jakma <paul.jakma@sun.com>paul
* zebra.h: BSD BYTE_ORDER define isn't available everywhere, define if needs be. * checksum.h: new file. checksum.c exports in_cksum, provide a header for it. * checksum.c: (in_cksum) callers shouldn't have to know it uses a u_short internally, change to void *. * Makefile.am: Add checksum.h * command.h: remove bogus trailling slash. * md5.c: (general) Update it for the twentieth century. ANSI declarations are widely supported now.. Don't include system headers, only include zebra.h. Use POSIX types (the alternative is to define u_int64_t in a portable way - rest of Quagga needs same cleanup). Make endian-conditional code be compiler conditional rather than preprocessor conditional, so that breakage gets noticed quicker. * md5.h: POSIX types. Get rid of the odd __P() non-ANSI capable compiler compatibility hack.