diff options
Diffstat (limited to 'isisd/iso_checksum.c')
-rw-r--r-- | isisd/iso_checksum.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/isisd/iso_checksum.c b/isisd/iso_checksum.c index 294fe994..abd101b9 100644 --- a/isisd/iso_checksum.c +++ b/isisd/iso_checksum.c @@ -75,3 +75,100 @@ iso_csum_verify (u_char * buffer, int len, uint16_t * csum) return 0; return 1; } +<<<<<<< HEAD:isisd/iso_checksum.c + +/* + * Creates the checksum. *csum points to the position of the checksum in the + * PDU. + * Based on Annex C.4 of ISO/IEC 8473 + */ +#define FIXED_CODE +u_int16_t +iso_csum_create (u_char * buffer, int len, u_int16_t n) +{ + + u_int8_t *p; + int x; + int y; + u_int32_t mul; + u_int32_t c0; + u_int32_t c1; + u_int16_t checksum; + u_int16_t *csum; + int i, init_len, partial_len; + + checksum = 0; + + /* + * Zero the csum in the packet. + */ + csum = (u_int16_t *) (buffer + n); + *(csum) = checksum; + + p = buffer; + c0 = 0; + c1 = 0; + init_len = len; + + while (len != 0) + { + 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; + } + + mul = (init_len - n)*(c0); + +#ifdef FIXED_CODE + x = mul - c0 - c1; + y = c1 - mul - 1; + + if (y > 0) + y++; + if (x < 0) + x--; + + x %= 255; + y %= 255; + + if (x == 0) + x = 255; + if (y == 0) + y = 1; + + checksum = (y << 8) | (x & 0xFF); + +#else + x = mul - c0 - c1; + x %= 255; + + y = c1 - mul - 1; + y %= 255; + + if (x == 0) + x = 255; + if (y == 0) + y = 255; + + checksum = ((y << 8) | x); +#endif + + /* + * Now we write this to the packet + */ + *(csum) = checksum; + + /* return the checksum for user usage */ + return checksum; +} +======= +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:isisd/iso_checksum.c |