diff options
Diffstat (limited to 'lib/checksum.c')
| -rw-r--r-- | lib/checksum.c | 148 | 
1 files changed, 73 insertions, 75 deletions
diff --git a/lib/checksum.c b/lib/checksum.c index 3d6cd45791..8eef73e243 100644 --- a/lib/checksum.c +++ b/lib/checksum.c @@ -9,13 +9,13 @@  #include <zebra.h>  #include "checksum.h" -int			/* return checksum in low-order 16 bits */ -in_cksum(void *parg, int nbytes) +int /* return checksum in low-order 16 bits */ +	in_cksum(void *parg, int nbytes)  {  	u_short *ptr = parg; -	register long		sum;		/* assumes long == 32 bits */ -	u_short			oddbyte; -	register u_short	answer;		/* assumes u_short == 16 bits */ +	register long sum; /* assumes long == 32 bits */ +	u_short oddbyte; +	register u_short answer; /* assumes u_short == 16 bits */  	/*  	 * Our algorithm is simple, using a 32-bit accumulator (sum), @@ -24,15 +24,15 @@ in_cksum(void *parg, int nbytes)  	 */  	sum = 0; -	while (nbytes > 1)  { +	while (nbytes > 1) {  		sum += *ptr++;  		nbytes -= 2;  	} -				/* mop up an odd byte, if necessary */ +	/* mop up an odd byte, if necessary */  	if (nbytes == 1) { -		oddbyte = 0;		/* make sure top half is zero */ -		*((u_char *) &oddbyte) = *(u_char *)ptr;   /* one byte only */ +		oddbyte = 0; /* make sure top half is zero */ +		*((u_char *)&oddbyte) = *(u_char *)ptr; /* one byte only */  		sum += oddbyte;  	} @@ -40,82 +40,80 @@ in_cksum(void *parg, int nbytes)  	 * Add back carry outs from top 16 bits to low 16 bits.  	 */ -	sum  = (sum >> 16) + (sum & 0xffff);	/* add high-16 to low-16 */ -	sum += (sum >> 16);			/* add carry */ -	answer = ~sum;		/* ones-complement, then truncate to 16 bits */ -	return(answer); +	sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */ +	sum += (sum >> 16);		    /* add carry */ +	answer = ~sum; /* ones-complement, then truncate to 16 bits */ +	return (answer);  }  /* Fletcher Checksum -- Refer to RFC1008. */  #define MODX                 4102U   /* 5802 should be fine */ -/* To be consistent, offset is 0-based index, rather than the 1-based  +/* To be consistent, offset is 0-based index, rather than the 1-based     index required in the specification ISO 8473, Annex C.1 */  /* calling with offset == FLETCHER_CHECKSUM_VALIDATE will validate the checksum     without modifying the buffer; a valid checksum returns 0 */ -u_int16_t -fletcher_checksum(u_char * buffer, const size_t len, const uint16_t offset) +u_int16_t fletcher_checksum(u_char *buffer, const size_t len, +			    const uint16_t offset)  { -  u_int8_t *p; -  int x, y, c0, c1; -  u_int16_t checksum = 0; -  u_int16_t *csum; -  size_t partial_len, i, left = len; -   -  if (offset != FLETCHER_CHECKSUM_VALIDATE) -    /* Zero the csum in the packet. */ -    { -      assert (offset < (len - 1)); /* account for two bytes of checksum */ -      csum = (u_int16_t *) (buffer + offset); -      *(csum) = 0; -    } - -  p = buffer; -  c0 = 0; -  c1 = 0; - -  while (left != 0) -    { -      partial_len = MIN(left, MODX); - -      for (i = 0; i < partial_len; i++) +	u_int8_t *p; +	int x, y, c0, c1; +	u_int16_t checksum = 0; +	u_int16_t *csum; +	size_t partial_len, i, left = len; + +	if (offset != FLETCHER_CHECKSUM_VALIDATE) +	/* Zero the csum in the packet. */  	{ -	  c0 = c0 + *(p++); -	  c1 += c0; +		assert(offset +		       < (len - 1)); /* account for two bytes of checksum */ +		csum = (u_int16_t *)(buffer + offset); +		*(csum) = 0;  	} -      c0 = c0 % 255; -      c1 = c1 % 255; - -      left -= partial_len; -    } - -  /* The cast is important, to ensure the mod is taken as a signed value. */ -  x = (int)((len - offset - 1) * c0 - c1) % 255; - -  if (x <= 0) -    x += 255; -  y = 510 - c0 - x; -  if (y > 255)   -    y -= 255; - -  if (offset == FLETCHER_CHECKSUM_VALIDATE) -    { -      checksum = (c1 << 8) + c0; -    } -  else -    { -      /* -       * Now we write this to the packet. -       * We could skip this step too, since the checksum returned would -       * be stored into the checksum field by the caller. -       */ -      buffer[offset] = x; -      buffer[offset + 1] = y; - -      /* Take care of the endian issue */ -      checksum = htons((x << 8) | (y & 0xFF)); -    } - -  return checksum; +	p = buffer; +	c0 = 0; +	c1 = 0; + +	while (left != 0) { +		partial_len = MIN(left, MODX); + +		for (i = 0; i < partial_len; i++) { +			c0 = c0 + *(p++); +			c1 += c0; +		} + +		c0 = c0 % 255; +		c1 = c1 % 255; + +		left -= partial_len; +	} + +	/* The cast is important, to ensure the mod is taken as a signed value. +	 */ +	x = (int)((len - offset - 1) * c0 - c1) % 255; + +	if (x <= 0) +		x += 255; +	y = 510 - c0 - x; +	if (y > 255) +		y -= 255; + +	if (offset == FLETCHER_CHECKSUM_VALIDATE) { +		checksum = (c1 << 8) + c0; +	} else { +		/* +		 * Now we write this to the packet. +		 * We could skip this step too, since the checksum returned +		 * would +		 * be stored into the checksum field by the caller. +		 */ +		buffer[offset] = x; +		buffer[offset + 1] = y; + +		/* Take care of the endian issue */ +		checksum = htons((x << 8) | (y & 0xFF)); +	} + +	return checksum;  }  | 
