Annotation of libelwix/src/crc.c, revision 1.1
1.1 ! misho 1: /*************************************************************************
! 2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
! 3: * by Michael Pounov <misho@openbsd-bg.org>
! 4: *
! 5: * $Author: misho $
! 6: * $Id: aitcrc.c,v 1.6 2012/07/22 21:46:23 misho Exp $
! 7: *
! 8: **************************************************************************
! 9: The ELWIX and AITNET software is distributed under the following
! 10: terms:
! 11:
! 12: All of the documentation and software included in the ELWIX and AITNET
! 13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
! 14:
! 15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
! 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
! 17:
! 18: Redistribution and use in source and binary forms, with or without
! 19: modification, are permitted provided that the following conditions
! 20: are met:
! 21: 1. Redistributions of source code must retain the above copyright
! 22: notice, this list of conditions and the following disclaimer.
! 23: 2. Redistributions in binary form must reproduce the above copyright
! 24: notice, this list of conditions and the following disclaimer in the
! 25: documentation and/or other materials provided with the distribution.
! 26: 3. All advertising materials mentioning features or use of this software
! 27: must display the following acknowledgement:
! 28: This product includes software developed by Michael Pounov <misho@elwix.org>
! 29: ELWIX - Embedded LightWeight unIX and its contributors.
! 30: 4. Neither the name of AITNET nor the names of its contributors
! 31: may be used to endorse or promote products derived from this software
! 32: without specific prior written permission.
! 33:
! 34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
! 35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 44: SUCH DAMAGE.
! 45: */
! 46: #include "global.h"
! 47:
! 48:
! 49: /* Adler module */
! 50: const u_int crc_modAdler = 0xFFF1L;
! 51:
! 52: /* All known library CRC types ... */
! 53: const crcPoly_t crc_Poly[] = {
! 54: { 1, (u_int) 0x1, "CRC-1-Parity" },
! 55: { 4, (u_int) 0x3, "CRC-4-ITU" },
! 56: { 5, (u_int) 0x15, "CRC-5-ITU" },
! 57: { 6, (u_int) 0x3, "CRC-6-ITU" },
! 58: { 7, (u_int) 0x9, "CRC-7-MMC" },
! 59: { 8, (u_int) 0x8D, "CRC-8-CCITT" },
! 60: { 10, (u_int) 0x233, "CRC-10" },
! 61: { 11, (u_int) 0x385, "CRC-11-FlexRay" },
! 62: { 12, (u_int) 0x80F, "CRC-12-Telco" },
! 63: { 15, (u_int) 0x4599, "CRC-15-CAN" },
! 64: { 16, (u_int) 0x8005, "CRC-16-IBM" },
! 65: { 24, (u_int) 0x864CFB, "CRC-24-Radix64" },
! 66: { 30, (u_int) 0x2030B9C7, "CRC-30-CDMA" },
! 67: { 32, (u_int) 0x04C11DB7, "CRC-32-802.3" }
! 68: };
! 69:
! 70:
! 71: /*
! 72: * crcReflect() - Reflect all bits of number
! 73: *
! 74: * @crcNum = Number for reflection
! 75: * @crcBits = Number width bits
! 76: * return: -1 error, !=-1 reflecting number
! 77: */
! 78: inline u_int
! 79: crcReflect(u_int crcNum, u_char crcBits)
! 80: {
! 81: register u_int i, j, rev;
! 82:
! 83: for (i = (u_int) 1 << (crcBits - 1), j = 1, rev ^= rev; i; i >>= 1, j <<= 1)
! 84: if (crcNum & i)
! 85: rev |= j;
! 86: return rev;
! 87: }
! 88:
! 89: /*
! 90: * crcCalc() - Generic CRC calculation function for many sub variants of CRC algorithms
! 91: *
! 92: * @psBuf = Data for calculation
! 93: * @bufLen = Length of data
! 94: * @crcBits = CRC algorithm bits (1, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 24, 30, 32)
! 95: * @RevOpts = Options for computation (REVOPTS_REVERTBYTE, REVOPTS_REVERTCRC)
! 96: * @initCRC = Initial CRC value
! 97: * @xorCRC = Last xor CRC value
! 98: * return: -1 error, !=-1 CRC checksum
! 99: */
! 100: inline u_int
! 101: crcCalc(u_char * __restrict psBuf, u_int bufLen, u_char crcBits, u_char RevOpts, u_int initCRC, u_int xorCRC)
! 102: {
! 103: const u_int bits = sizeof(int) * 8 - crcBits;
! 104: u_int poly, crchibit, crc;
! 105: register u_int i, j, b, ch;
! 106:
! 107: assert(psBuf);
! 108:
! 109: switch (crcBits) {
! 110: case 1:
! 111: poly = crc_Poly[0].poly_num;
! 112: break;
! 113: case 4:
! 114: poly = crc_Poly[1].poly_num;
! 115: break;
! 116: case 5:
! 117: poly = crc_Poly[2].poly_num;
! 118: break;
! 119: case 6:
! 120: poly = crc_Poly[3].poly_num;
! 121: break;
! 122: case 7:
! 123: poly = crc_Poly[4].poly_num;
! 124: break;
! 125: case 8:
! 126: poly = crc_Poly[5].poly_num;
! 127: break;
! 128: case 10:
! 129: poly = crc_Poly[6].poly_num;
! 130: break;
! 131: case 11:
! 132: poly = crc_Poly[7].poly_num;
! 133: break;
! 134: case 12:
! 135: poly = crc_Poly[8].poly_num;
! 136: break;
! 137: case 15:
! 138: poly = crc_Poly[9].poly_num;
! 139: break;
! 140: case 16:
! 141: poly = crc_Poly[10].poly_num;
! 142: break;
! 143: case 24:
! 144: poly = crc_Poly[11].poly_num;
! 145: break;
! 146: case 30:
! 147: poly = crc_Poly[12].poly_num;
! 148: break;
! 149: case 32:
! 150: poly = crc_Poly[13].poly_num;
! 151: break;
! 152: default:
! 153: elwix_SetErr(EINVAL, "crcCalc(): Unsupported CRC method!!!");
! 154: return -1;
! 155: }
! 156: poly <<= bits;
! 157:
! 158: crchibit = (u_int) 1 << (crcBits - 1);
! 159: crchibit <<= bits;
! 160: crc = initCRC << bits;
! 161:
! 162: for (i = 0; i < bufLen; i++) {
! 163: ch = (u_int) *psBuf++;
! 164: if (RevOpts & REVOPTS_REVERTBYTE)
! 165: ch = crcReflect(ch, 8);
! 166:
! 167: for (j = 0x80; j; j >>= 1) {
! 168: b = crc & crchibit;
! 169: crc <<= 1;
! 170:
! 171: if (ch & j)
! 172: b ^= crchibit;
! 173: if (b)
! 174: crc ^= poly;
! 175: }
! 176: }
! 177:
! 178: if (RevOpts & REVOPTS_REVERTCRC)
! 179: crc = crcReflect(crc, sizeof(int) * 8);
! 180: crc ^= xorCRC << bits;
! 181: crc &= (((crchibit - 1) << 1) | 1);
! 182: if (!(RevOpts & REVOPTS_REVERTCRC))
! 183: crc >>= bits;
! 184:
! 185: return crc;
! 186: }
! 187:
! 188:
! 189: /*
! 190: * crcIP() - Checksum in IP communication
! 191: *
! 192: * @buf = Data for calculation
! 193: * @bufLen = Length of data
! 194: * return: -1 error, !=-1 Checksum
! 195: */
! 196: inline u_short
! 197: crcIP(u_char * __restrict buf, int bufLen)
! 198: {
! 199: register u_int sum;
! 200: u_short last = 0, *nBuf = (u_short*) buf;
! 201:
! 202: assert(buf);
! 203:
! 204: for (sum = 0; bufLen && bufLen > 1; bufLen -= 2)
! 205: sum += *nBuf++;
! 206: if (bufLen == 1) {
! 207: *(u_char*)(&last) += *(u_char*) nBuf;
! 208: sum += last;
! 209: }
! 210:
! 211: sum = (sum >> 16) + (sum & 0xFFFF);
! 212: sum += sum >> 16;
! 213:
! 214: return (u_short) ~sum;
! 215: }
! 216:
! 217: /*
! 218: * crcFletcher16() - Fletcher-16 Checksum computing
! 219: *
! 220: * @nBuf = Data for calculation
! 221: * @bufLen = Length of data
! 222: * return: -1 error, !=-1 Checksum
! 223: */
! 224: inline u_short
! 225: crcFletcher16(u_short * __restrict nBuf, int bufLen)
! 226: {
! 227: register u_short s1, s2;
! 228: register u_int clen;
! 229:
! 230: assert(nBuf);
! 231:
! 232: s1 = s2 = 0xFF;
! 233: while (bufLen) {
! 234: clen = bufLen > MAX_FLETCHER16_DIGEST ? MAX_FLETCHER16_DIGEST : bufLen;
! 235: bufLen -= clen;
! 236:
! 237: do {
! 238: s1 += (u_short) *nBuf++;
! 239: s2 += s1;
! 240: } while (--clen);
! 241:
! 242: s1 = (s1 >> 8) + (s1 & 0xFF);
! 243: s2 = (s2 >> 8) + (s2 & 0xFF);
! 244: }
! 245:
! 246: return (s2 << 8) | s1;
! 247: }
! 248:
! 249: /*
! 250: * crcFletcher() - Fletcher-32 Checksum computing
! 251: *
! 252: * @nBuf = Data for calculation
! 253: * @bufLen = Length of data
! 254: * return: -1 error, !=-1 Checksum
! 255: */
! 256: inline u_int
! 257: crcFletcher(u_short * __restrict nBuf, int bufLen)
! 258: {
! 259: register u_int s1, s2, clen;
! 260:
! 261: assert(nBuf);
! 262:
! 263: s1 = s2 = 0xFFFF;
! 264: while (bufLen) {
! 265: clen = bufLen > MAX_FLETCHER_DIGEST ? MAX_FLETCHER_DIGEST : bufLen;
! 266: bufLen -= clen;
! 267:
! 268: do {
! 269: s1 += (u_int) *nBuf++;
! 270: s2 += s1;
! 271: } while (--clen);
! 272:
! 273: s1 = (s1 >> 16) + (s1 & 0xFFFF);
! 274: s2 = (s2 >> 16) + (s2 & 0xFFFF);
! 275: }
! 276:
! 277: return (s2 << 16) | s1;
! 278: }
! 279:
! 280: /*
! 281: * crcAdler() - crcAdler-32 Checksum computing
! 282: *
! 283: * @psBuf = Data for calculation
! 284: * @bufLen = Length of data
! 285: * return: -1 error, !=-1 Checksum
! 286: */
! 287: inline u_int
! 288: crcAdler(u_char * __restrict psBuf, int bufLen)
! 289: {
! 290: register u_int s1, s2, clen;
! 291:
! 292: assert(psBuf);
! 293:
! 294: s1 = 1L;
! 295: s2 ^= s2;
! 296: while (bufLen) {
! 297: clen = bufLen > MAX_ADLER_DIGEST ? MAX_ADLER_DIGEST : bufLen;
! 298: bufLen -= clen;
! 299:
! 300: do {
! 301: s1 += (u_int) *psBuf++;
! 302: s2 += s1;
! 303: } while (--clen);
! 304:
! 305: s1 %= crc_modAdler;
! 306: s2 %= crc_modAdler;
! 307: }
! 308:
! 309: return (s2 << 16) | s1;
! 310: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>