summaryrefslogtreecommitdiff
path: root/ospf6d
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_flood.c4
-rw-r--r--ospf6d/ospf6_lsa.c54
-rw-r--r--ospf6d/ospf6_lsa.h1
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);