*
* miscellaneous checksumming routines
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/checksum.c,v 1.4 2006-09-25 09:23:32 hannes Exp $";
-#endif
+#include <config.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <tcpdump-stdinc.h>
+#include "netdissect-stdinc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
-#include "interface.h"
+#include "netdissect.h"
/*
* CRC-10 table generated using the following Python snippet:
accum ^= 0x633
crc_table.append(accum)
-for i in range(len(crc_table)/8):
+for i in range(int(len(crc_table)/8)):
for j in range(8):
sys.stdout.write("0x%04x, " % crc_table[i*8+j])
sys.stdout.write("\n")
*/
-static const u_int16_t crc10_table[256] =
+static const uint16_t crc10_table[256] =
{
0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff,
0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe,
0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1
};
-static void
-init_crc10_table(void)
-{
-#define CRC10_POLYNOMIAL 0x633
- register int i, j;
- register u_int16_t accum;
- u_int16_t verify_crc10_table[256];
-
- for ( i = 0; i < 256; i++ )
- {
- accum = ((unsigned short) i << 2);
- for ( j = 0; j < 8; j++ )
- {
- if ((accum <<= 1) & 0x400) accum ^= CRC10_POLYNOMIAL;
- }
- verify_crc10_table[i] = accum;
- }
- assert(memcmp(verify_crc10_table,
- crc10_table,
- sizeof(verify_crc10_table)) == 0);
-#undef CRC10_POLYNOMIAL
-}
-
-u_int16_t
-verify_crc10_cksum(u_int16_t accum, const u_char *p, int length)
+uint16_t
+verify_crc10_cksum(uint16_t accum, const u_char *p, int length)
{
- register int i;
+ int i;
- for ( i = 0; i < length; i++ )
- {
+ for ( i = 0; i < length; i++ ) {
accum = ((accum << 8) & 0x3ff)
^ crc10_table[( accum >> 2) & 0xff]
^ *p++;
return accum;
}
-/* precompute checksum tables */
-void
-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)
+uint16_t
+create_osi_cksum (const uint8_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;
+ int32_t mul;
+ uint32_t c0;
+ uint64_t c1;
+ uint16_t checksum;
+ int idx;
c0 = 0;
c1 = 0;
- for (index = 0; index < length; index++) {
+ for (idx = 0; idx < length; idx++) {
/*
* Ignore the contents of the checksum field.
*/
- if (index == checksum_offset ||
- index == checksum_offset+1) {
+ if (idx == checksum_offset ||
+ idx == 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--;
+ /*
+ * Casting c0 and c1 here is guaranteed to be safe, because we know
+ * they have values between 0 and 254 inclusive. These casts are
+ * done to ensure that all of the arithmetic operations are
+ * well-defined (i.e., not mixing signed and unsigned integers).
+ */
+ x = mul - (int)c0 - (int)c1;
+ y = (int)c1 - mul;
x %= 255;
y %= 255;
-
- if (x == 0) x = 255;
- if (y == 0) y = 255;
+ if (x <= 0) x += 255;
+ if (y <= 0) y += 255;
y &= 0x00FF;
- checksum = ((x << 8) | y);
-
+ checksum = (uint16_t)((x << 8) | y);
+
return checksum;
}