summaryrefslogtreecommitdiff
path: root/ospfd
diff options
context:
space:
mode:
authorJingjing Duan <Jingjing.Duan@sun.com>2008-08-13 19:09:10 +0100
committerPaul Jakma <paul@quagga.net>2008-08-22 19:52:57 +0100
commit6a270cd93d02a88709e7292684db47552b630abf (patch)
tree8783ae29bef1f8e48e6278dcbe4360247316b029 /ospfd
parent3e40282fd93553da276b48830db3df819b73c884 (diff)
[ospfd/isisd] Switch to lib/ Fletcher checksum, fixing bug in isisd
2008-08-13 Jingjing Duan <Jingjing.Duan@sun.com> * ospfd/: Remove the old checksum implementation and use the consolidated version. * isisd/: ditto, thus fixing isisd checksuming on big-endian. Signed-off-by: Paul Jakma <paul@quagga.net>
Diffstat (limited to 'ospfd')
-rw-r--r--ospfd/ospf_lsa.c44
1 files changed, 11 insertions, 33 deletions
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 243928f4..f453353d 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -32,6 +32,7 @@
#include "thread.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
+#include "checksum.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -172,46 +173,23 @@ get_age (struct ospf_lsa *lsa)
/* Fletcher Checksum -- Refer to RFC1008. */
-#define MODX 4102
-#define LSA_CHECKSUM_OFFSET 15
+/* All the offsets are zero-based. The offsets in the RFC1008 are
+ one-based. */
u_int16_t
ospf_lsa_checksum (struct lsa_header *lsa)
{
- u_char *sp, *ep, *p, *q;
- int c0 = 0, c1 = 0;
- int x, y;
- u_int16_t length;
-
- lsa->checksum = 0;
- length = ntohs (lsa->length) - 2;
- sp = (u_char *) &lsa->options;
-
- for (ep = sp + length; sp < ep; sp = q)
- {
- q = sp + MODX;
- if (q > ep)
- q = ep;
- for (p = sp; p < q; p++)
- {
- c0 += *p;
- c1 += c0;
- }
- c0 %= 255;
- c1 %= 255;
- }
+ u_char *buffer = (u_char *) &lsa->options;
+ int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
- x = (((int)length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
- if (x <= 0)
- x += 255;
- y = 510 - c0 - x;
- if (y > 255)
- y -= 255;
+ /* Skip the AGE field */
+ u_int16_t len = ntohs(lsa->length) - options_offset;
- /* take care endian issue. */
- lsa->checksum = htons ((x << 8) + y);
+ /* Checksum offset starts from "options" field, not the beginning of the
+ lsa_header struct. The offset is 14, rather than 16. */
+ int checksum_offset = (u_char *) &lsa->checksum - buffer;
- return (lsa->checksum);
+ return fletcher_checksum(buffer, len, checksum_offset);
}