/* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobbs' * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC * values as ZMODEM and PKZIP * * Copyright (C) 2002-2005 SBE, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include #include "pmcc4_sysdep.h" #include "sbecom_inline_linux.h" #include "sbe_promformat.h" /* defines */ #define CRC32_POLYNOMIAL 0xEDB88320L #define CRC_TABLE_ENTRIES 256 static u_int32_t crcTableInit; #ifdef STATIC_CRC_TABLE static u_int32_t CRCTable[CRC_TABLE_ENTRIES]; #endif /*************************************************************************** * * genCrcTable - fills in CRCTable, as used by sbeCrc() * * RETURNS: N/A * * ERRNO: N/A ***************************************************************************/ static void genCrcTable (u_int32_t *CRCTable) { int ii, jj; u_int32_t crc; for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++) { crc = ii; for (jj = 8; jj > 0; jj--) { if (crc & 1) crc = (crc >> 1) ^ CRC32_POLYNOMIAL; else crc >>= 1; } CRCTable[ii] = crc; } crcTableInit++; } /*************************************************************************** * * sbeCrc - generates a CRC on a given buffer, and initial CRC * * This routine calculates the CRC for a buffer of data using the * table lookup method. It accepts an original value for the crc, * and returns the updated value. This permits "catenation" of * discontiguous buffers. An original value of 0 for the "first" * buffer is the norm. * * Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobb's * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC * values as ZMODEM and PKZIP. * * RETURNS: calculated crc of block * */ void sbeCrc (u_int8_t *buffer, /* data buffer to crc */ u_int32_t count, /* length of block in bytes */ u_int32_t initialCrc, /* starting CRC */ u_int32_t *result) { u_int32_t *tbl = 0; u_int32_t temp1, temp2, crc; /* * if table not yet created, do so. Don't care about "extra" time * checking this every time sbeCrc() is called, since CRC calculations are * already time consuming */ if (!crcTableInit) { #ifdef STATIC_CRC_TABLE tbl = &CRCTable; genCrcTable (tbl); #else tbl = (u_int32_t *) OS_kmalloc (CRC_TABLE_ENTRIES * sizeof (u_int32_t)); if (tbl == 0) { *result = 0; /* dummy up return value due to malloc * failure */ return; } genCrcTable (tbl); #endif } /* inverting bits makes ZMODEM & PKZIP compatible */ crc = initialCrc ^ 0xFFFFFFFFL; while (count-- != 0) { temp1 = (crc >> 8) & 0x00FFFFFFL; temp2 = tbl[((int) crc ^ *buffer++) & 0xff]; crc = temp1 ^ temp2; } crc ^= 0xFFFFFFFFL; *result = crc; #ifndef STATIC_CRC_TABLE crcTableInit = 0; OS_kfree (tbl); #endif } /*** End-of-File ***/