Annotation of libaitcrc/src/aitcrc.c, revision 1.1.1.1.2.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 $
1.1.1.1.2.1! misho 6: * $Id: aitcrc.c,v 1.1.1.1 2008/11/05 17:02:55 misho Exp $
1.1 misho 7: *
8: *************************************************************************/
9: #include "global.h"
10:
11:
12: static int crc_Errno;
13: static char crc_Error[MAX_STR + 1];
14:
1.1.1.1.2.1! misho 15: // Adler module
1.1 misho 16: const u_long crc_modAdler = 0xFFF1L;
17:
1.1.1.1.2.1! misho 18: // All known library CRC types ...
1.1 misho 19: const crcPoly_t crc_Poly[] = {
20: { 1, (u_long) 0x1, "CRC-1-Parity" },
21: { 4, (u_long) 0x3, "CRC-4-ITU" },
22: { 5, (u_long) 0x15, "CRC-5-ITU" },
23: { 6, (u_long) 0x3, "CRC-6-ITU" },
24: { 7, (u_long) 0x9, "CRC-7-MMC" },
25: { 8, (u_long) 0x8D, "CRC-8-CCITT" },
26: { 10, (u_long) 0x233, "CRC-10" },
27: { 11, (u_long) 0x385, "CRC-11-FlexRay" },
28: { 12, (u_long) 0x80F, "CRC-12-Telco" },
29: { 15, (u_long) 0x4599, "CRC-15-CAN" },
30: { 16, (u_long) 0x8005, "CRC-16-IBM" },
31: { 24, (u_long) 0x864CFB, "CRC-24-Radix64" },
32: { 30, (u_long) 0x2030B9C7, "CRC-30-CDMA" },
33: { 32, (u_long) 0x04C11DB7, "CRC-32-802.3" }
34: };
35:
36: // ----------------------------------------------------------
37:
1.1.1.1.2.1! misho 38: //
! 39: // Error maintenance functions ...
! 40: //
! 41:
! 42: // crc_GetErrno() Get error code of last operation
1.1 misho 43: inline int crc_GetErrno()
44: {
45: return crc_Errno;
46: }
47:
1.1.1.1.2.1! misho 48: // crc_GetError() Get error text of last operation
1.1 misho 49: inline const char *crc_GetError()
50: {
51: return crc_Error;
52: }
53:
54: // ----------------------------------------------------------
55:
1.1.1.1.2.1! misho 56: /*
! 57: * crcReflect() Reflect all bits of number
! 58: * @crcNum = Number for reflection
! 59: * @crcBits = Number width bits
! 60: * return: -1 error, !=-1 reflecting number
! 61: */
1.1 misho 62: inline u_long crcReflect(u_long crcNum, u_char crcBits)
63: {
64: register u_long i, j, rev;
65:
66: for (i = (u_long) 1 << (crcBits - 1), j = 1, rev ^= rev; i; i >>= 1, j <<= 1)
67: if (crcNum & i)
68: rev |= j;
69:
70: crc_Errno ^= crc_Errno;
71: return rev;
72: }
73:
1.1.1.1.2.1! misho 74: /*
! 75: * crcCalc() Generic CRC calculation function for many sub variants of CRC algorithms
! 76: * @psBuf = Data for calculation
! 77: * @bufLen = Length of data
! 78: * @crcBits = CRC algorithm bits (1, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 24, 30, 32)
! 79: * @RevOpts = Options for computation (REVOPTS_REVERTBYTE, REVOPTS_REVERTCRC)
! 80: * @initCRC = Initial CRC value
! 81: * @xorCRC = Last xor CRC value
! 82: * return: -1 error, !=-1 CRC checksum
! 83: */
1.1 misho 84: inline u_long crcCalc(u_char * __restrict psBuf, u_int bufLen, u_char crcBits, u_char RevOpts, u_long initCRC, u_long xorCRC)
85: {
86: const u_long bits = sizeof(long) * 8 - crcBits;
87: u_long poly, crchibit, crc;
88: register u_long i, j, b, ch;
89:
90: if (!psBuf) {
91: crc_Errno = 1;
92: strlcpy(crc_Error, "crcCalc(): Invalid parameters!", MAX_STR + 1);
93: return -1;
94: }
95:
96: switch (crcBits) {
97: case 1:
98: poly = crc_Poly[0].poly_num;
99: break;
100: case 4:
101: poly = crc_Poly[1].poly_num;
102: break;
103: case 5:
104: poly = crc_Poly[2].poly_num;
105: break;
106: case 6:
107: poly = crc_Poly[3].poly_num;
108: break;
109: case 7:
110: poly = crc_Poly[4].poly_num;
111: break;
112: case 8:
113: poly = crc_Poly[5].poly_num;
114: break;
115: case 10:
116: poly = crc_Poly[6].poly_num;
117: break;
118: case 11:
119: poly = crc_Poly[7].poly_num;
120: break;
121: case 12:
122: poly = crc_Poly[8].poly_num;
123: break;
124: case 15:
125: poly = crc_Poly[9].poly_num;
126: break;
127: case 16:
128: poly = crc_Poly[10].poly_num;
129: break;
130: case 24:
131: poly = crc_Poly[11].poly_num;
132: break;
133: case 30:
134: poly = crc_Poly[12].poly_num;
135: break;
136: case 32:
137: poly = crc_Poly[13].poly_num;
138: break;
139: default:
140: crc_Errno = 2;
141: strlcpy(crc_Error, "crcCalc(): Unsupported CRC method!!!", MAX_STR + 1);
142: return -1;
143: }
144: poly <<= bits;
145:
146: crchibit = (u_long) 1 << (crcBits - 1);
147: crchibit <<= bits;
148: crc = initCRC << bits;
149:
150: for (i = 0; i < bufLen; i++) {
151: ch = (u_long) *psBuf++;
152: if (RevOpts & REVOPTS_REVERTBYTE)
153: ch = crcReflect(ch, 8);
154:
155: for (j = 0x80; j; j >>= 1) {
156: b = crc & crchibit;
157: crc <<= 1;
158:
159: if (ch & j)
160: b ^= crchibit;
161: if (b)
162: crc ^= poly;
163: }
164: }
165:
166: if (RevOpts & REVOPTS_REVERTCRC)
167: crc = crcReflect(crc, sizeof(long) * 8);
168: crc ^= xorCRC << bits;
169: crc &= (((crchibit - 1) << 1) | 1);
170: if (!(RevOpts & REVOPTS_REVERTCRC))
171: crc >>= bits;
172:
173: crc_Errno ^= crc_Errno;
174: return crc;
175: }
176:
177: // ----------------------------------------------------------
178:
1.1.1.1.2.1! misho 179: /*
! 180: * crcIP() Checksum in IP communication
! 181: * @nBuf = Data for calculation
! 182: * @bufLen = Length of data
! 183: * return: -1 error, !=-1 Checksum
! 184: */
1.1 misho 185: inline u_short crcIP(u_short * __restrict nBuf, int bufLen)
186: {
187: register u_long sum;
188:
189: if (!nBuf) {
190: crc_Errno = 1;
191: strlcpy(crc_Error, "crcIP(): Invalid parameters!", MAX_STR + 1);
192: return -1;
193: }
194:
195: for (sum = 0; bufLen; bufLen--)
196: sum += *nBuf++;
197:
198: sum = (sum >> 16) + (sum & 0xFFFF);
199: sum += sum >> 16;
200:
201: crc_Errno ^= crc_Errno;
202: return (u_short) ~sum;
203: }
204:
1.1.1.1.2.1! misho 205: /*
! 206: * crcFletcher() Fletcher-16 Checksum computing
! 207: * @nBuf = Data for calculation
! 208: * @bufLen = Length of data
! 209: * return: -1 error, !=-1 Checksum
! 210: */
1.1 misho 211: inline u_long crcFletcher(u_short * __restrict nBuf, int bufLen)
212: {
213: register u_long s1, s2, clen;
214:
215: if (!nBuf) {
216: crc_Errno = 1;
217: strlcpy(crc_Error, "crcFletcher(): Invalid parameters!", MAX_STR + 1);
218: return -1;
219: }
220:
221: s1 = s2 = 0xFFFF;
222: while (bufLen) {
223: clen = bufLen > MAX_FLETCHER_DIGEST ? MAX_FLETCHER_DIGEST : bufLen;
224: bufLen -= clen;
225:
226: do {
227: s1 += (u_long) *nBuf++;
228: s2 += s1;
229: } while (--clen);
230:
231: s1 = (s1 >> 16) + (s1 & 0xFFFF);
232: s2 = (s2 >> 16) + (s2 & 0xFFFF);
233: }
234:
235: crc_Errno ^= crc_Errno;
236: return (s2 << 16) | s1;
237: }
238:
1.1.1.1.2.1! misho 239: /*
! 240: * crcAdler() crcAdler-32 Checksum computing
! 241: * @psBuf = Data for calculation
! 242: * @bufLen = Length of data
! 243: * return: -1 error, !=-1 Checksum
! 244: */
1.1 misho 245: inline u_long crcAdler(u_char * __restrict psBuf, int bufLen)
246: {
247: register u_long s1, s2, clen;
248:
249: if (!psBuf) {
250: crc_Errno = 1;
251: strlcpy(crc_Error, "crcAdler(): Invalid parameters!", MAX_STR + 1);
252: return -1;
253: }
254:
255: s1 = 1L;
256: s2 ^= s2;
257: while (bufLen) {
258: clen = bufLen > MAX_ADLER_DIGEST ? MAX_ADLER_DIGEST : bufLen;
259: bufLen -= clen;
260:
261: do {
262: s1 += (u_long) *psBuf++;
263: s2 += s1;
264: } while (--clen);
265:
266: s1 %= crc_modAdler;
267: s2 %= crc_modAdler;
268: }
269:
270: crc_Errno ^= crc_Errno;
271: return (s2 << 16) | s1;
272: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>