summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--proto/ospf/dbdes.c3
-rw-r--r--proto/ospf/lsalib.c87
-rw-r--r--proto/ospf/lsalib.h2
-rw-r--r--proto/ospf/lsupd.c26
-rw-r--r--proto/ospf/packet.c1
5 files changed, 78 insertions, 41 deletions
diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c
index ee2f96f9..c6aba363 100644
--- a/proto/ospf/dbdes.c
+++ b/proto/ospf/dbdes.c
@@ -189,11 +189,10 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct proto *p,
for(i=0;i<j;i++)
{
ntohlsah(plsa+i, &lsa);
- /* FIXME Test Checksum */
if(((he=ospf_hash_find(gr,lsa.id,lsa.rt,lsa.type))==NULL)||
(lsa_comp(&lsa, &(he->lsa))==1))
{
- /* Is this confition necessary? */
+ /* Is this condition necessary? */
if(ospf_hash_find(n->lsrqh,lsa.id,lsa.rt,lsa.type)==NULL)
{
sn=ospf_hash_get(n->lsrqh,lsa.id,lsa.rt,lsa.type);
diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c
index 72ca55c3..a7ef8040 100644
--- a/proto/ospf/lsalib.c
+++ b/proto/ospf/lsalib.c
@@ -230,62 +230,79 @@ ntohlsab(void *n, void *h, u8 type, u16 len)
#define LSA_CHECKSUM_OFFSET 15
/* FIXME This is VERY uneficient, I have huge endianity problems */
-
void
lsasum_calculate(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
{
+ u16 length;
+
+ length=h->length;
+
+ htonlsah(h,h);
+ htonlsab(body,body,h->type,length);
+
+ (void)lsasum_check(h,body,po);
+
+ ntohlsah(h,h);
+ ntohlsab(body,body,h->type,length);
+}
+
+/*
+ * Note, that this function expects that LSA is in big endianity
+ * It also returns value in big endian
+ */
+u16
+lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
+{
u8 *sp, *ep, *p, *q, *b;
int c0 = 0, c1 = 0;
int x, y;
- u16 length;
+ u16 length,chsum;
- h->checksum = 0;
b=body;
- length = h->length-2;
sp = (char *) &h->options;
-
- htonlsah(h,h);
- htonlsab(b,b,h->type,length+2);
+ length=ntohs(h->length)-2;
+ h->checksum = 0;
for (ep = sp + length; sp < ep; sp = q)
+ { /* Actually MODX is very large, do we need the for-cyclus? */
+ q = sp + MODX;
+ if (q > ep) q = ep;
+ for (p = sp; p < q; p++)
{
- q = sp + MODX;
- if (q > ep)
- q = ep;
- for (p = sp; p < q; p++)
- {
- if(p<(u8 *)(h+1))
- {
- c0 += *p;
- /*DBG("XXXXXX: %u\t%u\n", p-sp, *p);*/
- }
- else
- {
- c0 += *(b+(p-sp)-sizeof(struct ospf_lsa_header)+2);
- /*DBG("YYYYYY: %u\t%u\n", p-sp,*(b+(p-sp)-sizeof(struct ospf_lsa_header)+2));*/
- }
- c1 += c0;
- }
- c0 %= 255;
- c1 %= 255;
+ /*
+ * I count with bytes from header and than from body
+ * but if there is no body, it's appended to header
+ * (probably checksum in update receiving) and I go on
+ * after header
+ */
+ if((b==NULL) || (p<(u8 *)(h+1)))
+ {
+ c0 += *p;
+ }
+ else
+ {
+ c0 += *(b+(p-sp)-sizeof(struct ospf_lsa_header)+2);
+ }
+
+ c1 += c0;
}
+ c0 %= 255;
+ c1 %= 255;
+ }
x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
- if (x <= 0)
- x += 255;
+ if (x <= 0) x += 255;
y = 510 - c0 - x;
- if (y > 255)
- y -= 255;
+ if (y > 255) y -= 255;
- h->checksum = x + (y << 8);
-
- ntohlsah(h,h);
- ntohlsab(b,b,h->type,length+2);
+ chsum= x + (y << 8);
+ h->checksum = chsum;
+ return chsum;
}
int
lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
- /* Return codes form view of l1 */
+ /* Return codes from point of view of l1 */
{
if(l1->sn<l2->sn) return CMP_NEWER;
if(l1->sn==l2->sn)
diff --git a/proto/ospf/lsalib.h b/proto/ospf/lsalib.h
index b6547c76..5332d2ef 100644
--- a/proto/ospf/lsalib.h
+++ b/proto/ospf/lsalib.h
@@ -16,6 +16,8 @@ void htonlsab(void *h, void *n, u8 type, u16 len);
void ntohlsab(void *n, void *h, u8 type, u16 len);
void lsasum_calculate(struct ospf_lsa_header *header, void *body,
struct proto_ospf *p);
+u16 lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po);
+
#define CMP_NEWER 1
#define CMP_SAME 0
#define CMP_OLDER -1
diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c
index 8f9d6aa9..2fa01378 100644
--- a/proto/ospf/lsupd.c
+++ b/proto/ospf/lsupd.c
@@ -83,10 +83,10 @@ void
ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
struct ospf_iface *ifa, u16 size)
{
- u32 nrid, myrid;
+ u32 area,nrid,myrid;
struct ospf_neighbor *n;
- struct ospf_lsreq_header *lsh;
- int length;
+ struct ospf_lsa_header *lsa;
+ u16 length;
u8 i;
nrid=ntohl(ps->ospf_packet.routerid);
@@ -99,6 +99,24 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
nrid);
return ;
}
- /* FIXME Go on! */
+ if(n->state<NEIGHBOR_EXCHANGE)
+ {
+ debug("%s: Received lsupd in lesser state than EXCHANGE from (%u)\n",
+ p->name);
+ return;
+ }
+
+ lsa=(struct ospf_lsa_header *)(ps+1);
+ area=htonl(ps->ospf_packet.areaid);
+ for(i=0;i<ntohl(ps->lsano);i++)
+ {
+ if(lsa->checksum==lsasum_check(lsa,NULL,(struct proto_ospf *)p))
+ {
+ DBG("Processing update Type: %u ID: %u RT: %u\n",lsa->type,
+ ntohl(lsa->id), ntohl(lsa->rt));
+ /* FIXME Go on */
+ }
+ lsa=(struct ospf_lsa_header *)(((u8 *)lsa)+ntohs(lsa->length));
+ }
}
diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c
index a176c44e..8cc308a0 100644
--- a/proto/ospf/packet.c
+++ b/proto/ospf/packet.c
@@ -145,6 +145,7 @@ ospf_rx_hook(sock *sk, int size)
break;
case LSUPD:
DBG("%s: Link state update received.\n", p->name);
+ ospf_lsupd_rx((struct ospf_lsupd_packet *)ps, p, ifa, size);
break;
case LSACK:
DBG("%s: Link state ack received.\n", p->name);