/* * CRC routines needed for DOCSIS * * */ #include #include #include #include "crc.h" /* Global table data for the functions. Must call 'crctabinit' before using. */ static unsigned int crc16tab[256]; static unsigned int crc16tabnew[256]; static unsigned long crc32tab[256]; /* Globals used to compute CRCs */ static unsigned long CRC; static unsigned int HCS; /* Local working functions */ unsigned long calc32crc(unsigned int C); unsigned int calc16crc(unsigned int C); void crctabinit(void); /* #define MAIN*/ #ifdef MAIN main(int argc, char **argv) { unsigned char test1[200]; unsigned short crc16; unsigned long crc32; unsigned char ieeetest[] = { 0x01, 0xE0, 0x2F, 0x00, 0x00, 0x01, 0x01, 0xE0, 0x2F, 0x00, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x09, 0x0A, 0x0B, 0x0C }; // The CRC32 that should be appended is: D5 D9 DC E9 /* initialize CRC engines */ initialize_crc(); test1[0] = 0xC0; test1[1] = 0x00; test1[2] = 0x00; test1[3] = 0x1C; crc16 = compute_crc16 (test1, 4); printf ("\nTest string is: C0 00 00 1C, crc16=%x\n", crc16); crc32 = compute_crc32 (ieeetest, 24); printf ("\ncrc32=%x\n", crc32); test1[0] = 0x01; test1[1] = 0x05; test1[2] = 0x00; test1[3] = 0x2b; test1[4] = 0x44; test1[5] = 0x01; test1[6] = 0xba; test1[7] = 0x64; test1[8] = 0x00; //ba //c8 crc16 = compute_crc16 (test1, 9); printf ("\nTest string is: 01 05 .. 64 00, crc16=%x\n", crc16); } /* end of main */ #endif void initialize_crc () { crctabinit(); } void crctabinit(void) { int i,n; unsigned long CRC32; unsigned int CRC16; for (i=0;i<256;i++) { CRC32=i; for (n=1;n<9;n++) { if (CRC32 & 1) CRC32 = (CRC32 >> 1) ^ /* XOR */ 0xedb88320; else CRC32 = CRC32 >> 1; } crc32tab[i] = CRC32; } for (i=0;i<256;i++) { CRC16=i; for (n=1;n<9;n++) { if (CRC16 & 1) CRC16=(CRC16 >> 1) ^ 0xA001; else CRC16=CRC16 >> 1; } crc16tab[i]=CRC16; } for (i=0;i<256;i++) { CRC16=i; for (n=1;n<9;n++) { if (CRC16 & 1) CRC16=(CRC16 >> 1) ^ 0x8408; else CRC16=CRC16 >> 1; } crc16tabnew[i]=CRC16; } } unsigned long compute_crc32 (unsigned char *p, int n) { int i; unsigned long x, swapped_x; CRC = 0xffffffffL; for (i=0; i> 8) & 0x0000FF00); swapped_x |= ((x >> 24) & 0x000000FF); return swapped_x; } unsigned short compute_crc16 (unsigned char *p, int n) { int i; unsigned short x, swapped_x; HCS = 0xffff; for (i=0; i> 8; return swapped_x; } /* CCITT CRC-32 */ unsigned long calc32crc(unsigned int C) { CRC=crc32tab[(CRC ^ C) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL); return CRC ^ 0xffffffffL; } /* CCITT CRC-16 */ unsigned int calc16crc(unsigned int C) { HCS=((HCS >> 8) & 0x00ff) ^ crc16tabnew[(HCS ^ C) & 0x00ff]; return HCS ^ 0xffff; }