Second part of fixes from Laurent Rabret.
diff --git a/isisd/iso_checksum.c b/isisd/iso_checksum.c
index e65f6ef..eabe281 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 @@
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 @@
c0 = 0;
c1 = 0;
- for (i = 0; i < len; i++)
+ while (len)
{
- c0 = c0 + *(p++);
- c1 += c0;
- }
+ partial_len = MIN(len, 5803);
- c0 = c0 % 255;
- c1 = c1 % 255;
+ for (i = 0; i < partial_len; i++)
+ {
+ c0 = c0 + *(p++);
+ c1 += c0;
+ }
+
+ c0 = c0 % 255;
+ c1 = c1 % 255;
+
+ len -= partial_len;
+ }
if (c0 == 0 && c1 == 0)
return 0;
@@ -96,9 +102,6 @@
* 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 @@
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 @@
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;
+
+ len -= partial_len;
}
- c0 = c0 % 255;
- c1 = c1 % 255;
-
- 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 @@
if (x == 0)
x = 255;
if (y == 0)
- y = 255;
+ y = 1;
- x &= 0x00FF;
-
- checksum = ((y << 8) | x);
+ checksum = (y << 8) | (x & 0xFF);
#else
x = mul - c0 - c1;