diff options
Diffstat (limited to 'ospf6d')
-rw-r--r-- | ospf6d/ospf6_flood.c | 4 | ||||
-rw-r--r-- | ospf6d/ospf6_lsa.c | 54 | ||||
-rw-r--r-- | ospf6d/ospf6_lsa.h | 1 |
3 files changed, 24 insertions, 35 deletions
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 670c5d1d..b8159729 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -733,7 +733,6 @@ ospf6_receive_lsa (struct ospf6_neighbor *from, { struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL; int ismore_recent; - unsigned short cksum; int is_debug = 0; ismore_recent = 1; @@ -751,8 +750,7 @@ ospf6_receive_lsa (struct ospf6_neighbor *from, } /* (1) LSA Checksum */ - cksum = ntohs (new->header->checksum); - if (ntohs (ospf6_lsa_checksum (new->header)) != cksum) + if (! ospf6_lsa_checksum_valid (new->header)) { if (is_debug) zlog_debug ("Wrong LSA Checksum, discard"); diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index e65752d8..ff061dfb 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -29,6 +29,7 @@ #include "command.h" #include "memory.h" #include "thread.h" +#include "checksum.h" #include "ospf6_proto.h" #include "ospf6_lsa.h" @@ -672,47 +673,36 @@ ospf6_lsa_refresh (struct thread *thread) -/* enhanced Fletcher checksum algorithm, RFC1008 7.2 */ -#define MODX 4102 -#define LSA_CHECKSUM_OFFSET 15 +/* Fletcher Checksum -- Refer to RFC1008. */ +/* All the offsets are zero-based. The offsets in the RFC1008 are + one-based. */ unsigned short ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header) { - u_char *sp, *ep, *p, *q; - int c0 = 0, c1 = 0; - int x, y; - u_int16_t length; + u_char *buffer = (u_char *) &lsa_header->type; + int type_offset = buffer - (u_char *) &lsa_header->age; /* should be 2 */ - lsa_header->checksum = 0; - length = ntohs (lsa_header->length) - 2; - sp = (u_char *) &lsa_header->type; + /* Skip the AGE field */ + u_int16_t len = ntohs(lsa_header->length) - type_offset; - 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; - } + /* Checksum offset starts from "type" field, not the beginning of the + lsa_header struct. The offset is 14, rather than 16. */ + int checksum_offset = (u_char *) &lsa_header->checksum - buffer; + + return (unsigned short)fletcher_checksum(buffer, len, checksum_offset); +} - /* r = (c1 << 8) + c0; */ - x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255; - if (x <= 0) - x += 255; - y = 510 - c0 - x; - if (y > 255) - y -= 255; +int +ospf6_lsa_checksum_valid (struct ospf6_lsa_header *lsa_header) +{ + u_char *buffer = (u_char *) &lsa_header->type; + int type_offset = buffer - (u_char *) &lsa_header->age; /* should be 2 */ - lsa_header->checksum = htons ((x << 8) + y); + /* Skip the AGE field */ + u_int16_t len = ntohs(lsa_header->length) - type_offset; - return (lsa_header->checksum); + return (fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0); } void diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index 7d93f5cb..263411fc 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -237,6 +237,7 @@ extern int ospf6_lsa_expire (struct thread *); extern int ospf6_lsa_refresh (struct thread *); extern unsigned short ospf6_lsa_checksum (struct ospf6_lsa_header *); +extern int ospf6_lsa_checksum_valid (struct ospf6_lsa_header *); extern int ospf6_lsa_prohibited_duration (u_int16_t type, u_int32_t id, u_int32_t adv_router, void *scope); |