diff options
Diffstat (limited to 'isisd/iso_checksum.c')
-rw-r--r-- | isisd/iso_checksum.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/isisd/iso_checksum.c b/isisd/iso_checksum.c index e65f6ef6..eabe281f 100644 --- a/isisd/iso_checksum.c +++ b/isisd/iso_checksum.c @@ -42,7 +42,6 @@ * Verifies that the checksum is correct. * Return 0 on correct and 1 on invalid checksum. * Based on Annex C.4 of ISO/IEC 8473 - * FIXME: Check for overflow */ int @@ -52,7 +51,7 @@ iso_csum_verify (u_char * buffer, int len, uint16_t * csum) u_int32_t c0; u_int32_t c1; u_int16_t checksum; - int i; + int i, partial_len; p = buffer; checksum = 0; @@ -77,14 +76,21 @@ iso_csum_verify (u_char * buffer, int len, uint16_t * csum) c0 = 0; c1 = 0; - for (i = 0; i < len; i++) + while (len) { - c0 = c0 + *(p++); - c1 += c0; - } + partial_len = MIN(len, 5803); + + for (i = 0; i < partial_len; i++) + { + c0 = c0 + *(p++); + c1 += c0; + } - c0 = c0 % 255; - c1 = c1 % 255; + c0 = c0 % 255; + c1 = c1 % 255; + + len -= partial_len; + } if (c0 == 0 && c1 == 0) return 0; @@ -96,9 +102,6 @@ iso_csum_verify (u_char * buffer, int len, uint16_t * csum) * Creates the checksum. *csum points to the position of the checksum in the * PDU. * Based on Annex C.4 of ISO/IEC 8473 - * we will not overflow until about length of 6000, - * which is the answer to (255+255n)*n/2 > 2^32 - * so if we have a length of over 5000 we will return zero (for now) */ #define FIXED_CODE u_int16_t @@ -113,7 +116,7 @@ iso_csum_create (u_char * buffer, int len, u_int16_t n) u_int32_t c1; u_int16_t checksum; u_int16_t *csum; - int i; + int i, init_len, partial_len; checksum = 0; @@ -123,32 +126,34 @@ iso_csum_create (u_char * buffer, int len, u_int16_t n) csum = (u_int16_t *) (buffer + n); *(csum) = checksum; - /* for the limitation of our implementation */ - if (len > 5000) - { - return 0; - } - p = buffer; c0 = 0; c1 = 0; + init_len = len; - for (i = 0; i < len; i++) + while (len != 0) { - c0 = c0 + *(p++); - c1 += c0; - } + partial_len = MIN(len, 5803); + + for (i = 0; i < partial_len; i++) + { + c0 = c0 + *(p++); + c1 += c0; + } - c0 = c0 % 255; - c1 = c1 % 255; + c0 = c0 % 255; + c1 = c1 % 255; + + len -= partial_len; + } - mul = (len - n) * (c0); + mul = (init_len - n)*(c0); #ifdef FIXED_CODE x = mul - c0 - c1; y = c1 - mul - 1; - if (y >= 0) + if (y > 0) y++; if (x < 0) x--; @@ -159,11 +164,9 @@ iso_csum_create (u_char * buffer, int len, u_int16_t n) if (x == 0) x = 255; if (y == 0) - y = 255; - - x &= 0x00FF; + y = 1; - checksum = ((y << 8) | x); + checksum = (y << 8) | (x & 0xFF); #else x = mul - c0 - c1; |