diff options
-rw-r--r-- | proto/ospf/dbdes.c | 3 | ||||
-rw-r--r-- | proto/ospf/lsalib.c | 87 | ||||
-rw-r--r-- | proto/ospf/lsalib.h | 2 | ||||
-rw-r--r-- | proto/ospf/lsupd.c | 26 | ||||
-rw-r--r-- | proto/ospf/packet.c | 1 |
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); |