Revision 394acced proto/ospf/lsalib.c

View differences:

proto/ospf/lsalib.c
230 230
#define LSA_CHECKSUM_OFFSET    15
231 231

  
232 232
/* FIXME This is VERY uneficient, I have huge endianity problems */
233

  
234 233
void
235 234
lsasum_calculate(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
236 235
{
236
  u16 length;
237
  
238
  length=h->length;
239

  
240
  htonlsah(h,h);
241
  htonlsab(body,body,h->type,length);
242

  
243
  (void)lsasum_check(h,body,po);
244
  
245
  ntohlsah(h,h);
246
  ntohlsab(body,body,h->type,length);
247
}
248

  
249
/*
250
 * Note, that this function expects that LSA is in big endianity
251
 * It also returns value in big endian
252
 */
253
u16
254
lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
255
{
237 256
  u8 *sp, *ep, *p, *q, *b;
238 257
  int c0 = 0, c1 = 0;
239 258
  int x, y;
240
  u16 length;
259
  u16 length,chsum;
241 260

  
242
  h->checksum = 0;
243 261
  b=body;
244
  length = h->length-2;
245 262
  sp = (char *) &h->options;
246

  
247
  htonlsah(h,h);
248
  htonlsab(b,b,h->type,length+2);
263
  length=ntohs(h->length)-2;
264
  h->checksum = 0;
249 265

  
250 266
  for (ep = sp + length; sp < ep; sp = q)
267
  {		/* Actually MODX is very large, do we need the for-cyclus? */
268
    q = sp + MODX;
269
    if (q > ep) q = ep;
270
    for (p = sp; p < q; p++)
251 271
    {
252
      q = sp + MODX;
253
      if (q > ep)
254
        q = ep;
255
      for (p = sp; p < q; p++)
256
        {
257
          if(p<(u8 *)(h+1))
258
	  {
259
            c0 += *p;
260
	    /*DBG("XXXXXX: %u\t%u\n", p-sp, *p);*/
261
	  }
262
	  else
263
          {
264
            c0 += *(b+(p-sp)-sizeof(struct ospf_lsa_header)+2);
265
	    /*DBG("YYYYYY: %u\t%u\n", p-sp,*(b+(p-sp)-sizeof(struct ospf_lsa_header)+2));*/
266
          }
267
          c1 += c0;
268
        }
269
      c0 %= 255;
270
      c1 %= 255;
272
      /* 
273
       * I count with bytes from header and than from body
274
       * but if there is no body, it's appended to header
275
       * (probably checksum in update receiving) and I go on
276
       * after header
277
       */
278
      if((b==NULL) || (p<(u8 *)(h+1)))
279
      {
280
	      c0 += *p;
281
      }
282
      else
283
      {
284
	      c0 += *(b+(p-sp)-sizeof(struct ospf_lsa_header)+2);
285
      }
286

  
287
      c1 += c0;
271 288
    }
289
    c0 %= 255;
290
    c1 %= 255;
291
  }
272 292

  
273 293
  x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
274
  if (x <= 0)
275
    x += 255;
294
  if (x <= 0) x += 255;
276 295
  y = 510 - c0 - x;
277
  if (y > 255)
278
    y -= 255;
296
  if (y > 255) y -= 255;
279 297

  
280
  h->checksum = x + (y << 8);
281
  
282
  ntohlsah(h,h);
283
  ntohlsab(b,b,h->type,length+2);
298
  chsum= x + (y << 8);
299
  h->checksum = chsum;
300
  return chsum;
284 301
}
285 302

  
286 303
int
287 304
lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
288
			/* Return codes form view of l1 */
305
			/* Return codes from point of view of l1 */
289 306
{
290 307
  if(l1->sn<l2->sn) return CMP_NEWER;
291 308
    if(l1->sn==l2->sn)

Also available in: Unified diff