diff options
author | hannes <hannes> | 2006-09-25 09:23:32 +0000 |
---|---|---|
committer | hannes <hannes> | 2006-09-25 09:23:32 +0000 |
commit | 96977962e98d44c5144164e2286434418ded0e30 (patch) | |
tree | 522b5d26cb5b5d19b1d98ab84b5cedbf7aa098b5 /checksum.c | |
parent | d7da1619b5f30dc84f0303ce025a8df04b8a42f8 (diff) | |
download | tcpdump-96977962e98d44c5144164e2286434418ded0e30.tar.gz |
print shouldbe checksum for broken OSI checksum, remove osi_cksum()
Diffstat (limited to 'checksum.c')
-rw-r--r-- | checksum.c | 61 |
1 files changed, 60 insertions, 1 deletions
@@ -19,7 +19,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/checksum.c,v 1.3 2006-02-09 21:34:38 hannes Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/checksum.c,v 1.4 2006-09-25 09:23:32 hannes Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -76,3 +76,62 @@ init_checksum(void) { init_crc10_table(); } + +/* + * Creates the OSI Fletcher checksum. See 8473-1, Appendix C, section C.3. + * The checksum field of the passed PDU does not need to be reset to zero. + */ +u_int16_t +create_osi_cksum (const u_int8_t *pptr, int checksum_offset, int length) +{ + + int x; + int y; + u_int32_t mul; + u_int32_t c0; + u_int32_t c1; + u_int16_t checksum; + int index; + + checksum = 0; + + c0 = 0; + c1 = 0; + + for (index = 0; index < length; index++) { + /* + * Ignore the contents of the checksum field. + */ + if (index == checksum_offset || + index == checksum_offset+1) { + c1 += c0; + pptr++; + } else { + c0 = c0 + *(pptr++); + c1 += c0; + } + } + + c0 = c0 % 255; + c1 = c1 % 255; + + mul = (length - checksum_offset)*(c0); + + 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 = 255; + + y &= 0x00FF; + checksum = ((x << 8) | y); + + return checksum; +} |