diff options
Diffstat (limited to 'proto/ospf/lsalib.c')
-rw-r--r-- | proto/ospf/lsalib.c | 87 |
1 files changed, 52 insertions, 35 deletions
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) |