Annotation of libaitcrc/src/aitcrc.c, revision 1.2.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.2.2.1 ! misho 6: * $Id: aitcrc.c,v 1.2 2010/01/20 00:04:45 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.2 misho 15: // Adler module
1.2.2.1 ! misho 16: const u_int crc_modAdler = 0xFFF1L;
1.1 misho 17:
1.2 misho 18: // All known library CRC types ...
1.1 misho 19: const crcPoly_t crc_Poly[] = {
1.2.2.1 ! misho 20: { 1, (u_int) 0x1, "CRC-1-Parity" },
! 21: { 4, (u_int) 0x3, "CRC-4-ITU" },
! 22: { 5, (u_int) 0x15, "CRC-5-ITU" },
! 23: { 6, (u_int) 0x3, "CRC-6-ITU" },
! 24: { 7, (u_int) 0x9, "CRC-7-MMC" },
! 25: { 8, (u_int) 0x8D, "CRC-8-CCITT" },
! 26: { 10, (u_int) 0x233, "CRC-10" },
! 27: { 11, (u_int) 0x385, "CRC-11-FlexRay" },
! 28: { 12, (u_int) 0x80F, "CRC-12-Telco" },
! 29: { 15, (u_int) 0x4599, "CRC-15-CAN" },
! 30: { 16, (u_int) 0x8005, "CRC-16-IBM" },
! 31: { 24, (u_int) 0x864CFB, "CRC-24-Radix64" },
! 32: { 30, (u_int) 0x2030B9C7, "CRC-30-CDMA" },
! 33: { 32, (u_int) 0x04C11DB7, "CRC-32-802.3" }
1.1 misho 34: };
35:
36: // ----------------------------------------------------------
37:
1.2 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.2 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:
1.2 misho 54: // crcSetErr() Set error to variables for internal use!!!
55: inline void crcSetErr(int eno, char *estr, ...)
56: {
57: va_list lst;
58:
59: crc_Errno = eno;
60: memset(crc_Error, 0, MAX_STR + 1);
61: va_start(lst, estr);
62: vsnprintf(crc_Error, MAX_STR + 1, estr, lst);
63: va_end(lst);
64: }
65:
1.1 misho 66: // ----------------------------------------------------------
67:
1.2 misho 68: /*
69: * crcReflect() Reflect all bits of number
70: * @crcNum = Number for reflection
71: * @crcBits = Number width bits
72: * return: -1 error, !=-1 reflecting number
73: */
1.2.2.1 ! misho 74: inline u_int
! 75: crcReflect(u_int crcNum, u_char crcBits)
1.1 misho 76: {
1.2.2.1 ! misho 77: register u_int i, j, rev;
1.1 misho 78:
1.2.2.1 ! misho 79: for (i = (u_int) 1 << (crcBits - 1), j = 1, rev ^= rev; i; i >>= 1, j <<= 1)
1.1 misho 80: if (crcNum & i)
81: rev |= j;
82:
83: crc_Errno ^= crc_Errno;
84: return rev;
85: }
86:
1.2 misho 87: /*
88: * crcCalc() Generic CRC calculation function for many sub variants of CRC algorithms
89: * @psBuf = Data for calculation
90: * @bufLen = Length of data
91: * @crcBits = CRC algorithm bits (1, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 24, 30, 32)
92: * @RevOpts = Options for computation (REVOPTS_REVERTBYTE, REVOPTS_REVERTCRC)
93: * @initCRC = Initial CRC value
94: * @xorCRC = Last xor CRC value
95: * return: -1 error, !=-1 CRC checksum
96: */
1.2.2.1 ! misho 97: inline u_int
! 98: crcCalc(u_char * __restrict psBuf, u_int bufLen, u_char crcBits, u_char RevOpts, u_int initCRC, u_int xorCRC)
1.1 misho 99: {
1.2.2.1 ! misho 100: const u_int bits = sizeof(int) * 8 - crcBits;
! 101: u_int poly, crchibit, crc;
! 102: register u_int i, j, b, ch;
1.1 misho 103:
104: if (!psBuf) {
105: crc_Errno = 1;
106: strlcpy(crc_Error, "crcCalc(): Invalid parameters!", MAX_STR + 1);
107: return -1;
108: }
109:
110: switch (crcBits) {
111: case 1:
112: poly = crc_Poly[0].poly_num;
113: break;
114: case 4:
115: poly = crc_Poly[1].poly_num;
116: break;
117: case 5:
118: poly = crc_Poly[2].poly_num;
119: break;
120: case 6:
121: poly = crc_Poly[3].poly_num;
122: break;
123: case 7:
124: poly = crc_Poly[4].poly_num;
125: break;
126: case 8:
127: poly = crc_Poly[5].poly_num;
128: break;
129: case 10:
130: poly = crc_Poly[6].poly_num;
131: break;
132: case 11:
133: poly = crc_Poly[7].poly_num;
134: break;
135: case 12:
136: poly = crc_Poly[8].poly_num;
137: break;
138: case 15:
139: poly = crc_Poly[9].poly_num;
140: break;
141: case 16:
142: poly = crc_Poly[10].poly_num;
143: break;
144: case 24:
145: poly = crc_Poly[11].poly_num;
146: break;
147: case 30:
148: poly = crc_Poly[12].poly_num;
149: break;
150: case 32:
151: poly = crc_Poly[13].poly_num;
152: break;
153: default:
154: crc_Errno = 2;
155: strlcpy(crc_Error, "crcCalc(): Unsupported CRC method!!!", MAX_STR + 1);
156: return -1;
157: }
158: poly <<= bits;
159:
1.2.2.1 ! misho 160: crchibit = (u_int) 1 << (crcBits - 1);
1.1 misho 161: crchibit <<= bits;
162: crc = initCRC << bits;
163:
164: for (i = 0; i < bufLen; i++) {
1.2.2.1 ! misho 165: ch = (u_int) *psBuf++;
1.1 misho 166: if (RevOpts & REVOPTS_REVERTBYTE)
167: ch = crcReflect(ch, 8);
168:
169: for (j = 0x80; j; j >>= 1) {
170: b = crc & crchibit;
171: crc <<= 1;
172:
173: if (ch & j)
174: b ^= crchibit;
175: if (b)
176: crc ^= poly;
177: }
178: }
179:
180: if (RevOpts & REVOPTS_REVERTCRC)
1.2.2.1 ! misho 181: crc = crcReflect(crc, sizeof(int) * 8);
1.1 misho 182: crc ^= xorCRC << bits;
183: crc &= (((crchibit - 1) << 1) | 1);
184: if (!(RevOpts & REVOPTS_REVERTCRC))
185: crc >>= bits;
186:
187: crc_Errno ^= crc_Errno;
188: return crc;
189: }
190:
191: // ----------------------------------------------------------
192:
1.2 misho 193: /*
194: * crcIP() Checksum in IP communication
195: * @nBuf = Data for calculation
196: * @bufLen = Length of data
197: * return: -1 error, !=-1 Checksum
198: */
1.2.2.1 ! misho 199: inline u_short
! 200: crcIP(u_short * __restrict nBuf, int bufLen)
1.1 misho 201: {
1.2.2.1 ! misho 202: register u_int sum;
1.1 misho 203:
204: if (!nBuf) {
205: crc_Errno = 1;
206: strlcpy(crc_Error, "crcIP(): Invalid parameters!", MAX_STR + 1);
207: return -1;
208: }
209:
210: for (sum = 0; bufLen; bufLen--)
211: sum += *nBuf++;
212:
213: sum = (sum >> 16) + (sum & 0xFFFF);
214: sum += sum >> 16;
215:
216: crc_Errno ^= crc_Errno;
217: return (u_short) ~sum;
218: }
219:
1.2 misho 220: /*
1.2.2.1 ! misho 221: * crcFletcher16() Fletcher-16 Checksum computing
1.2 misho 222: * @nBuf = Data for calculation
223: * @bufLen = Length of data
224: * return: -1 error, !=-1 Checksum
225: */
1.2.2.1 ! misho 226: inline u_short
! 227: crcFletcher16(u_short * __restrict nBuf, int bufLen)
1.1 misho 228: {
1.2.2.1 ! misho 229: register u_short s1, s2;
! 230: register u_int clen;
! 231:
! 232: if (!nBuf) {
! 233: crc_Errno = 1;
! 234: strlcpy(crc_Error, "crcFletcher16(): Invalid parameters!", MAX_STR + 1);
! 235: return -1;
! 236: }
! 237:
! 238: s1 = s2 = 0xFF;
! 239: while (bufLen) {
! 240: clen = bufLen > MAX_FLETCHER16_DIGEST ? MAX_FLETCHER16_DIGEST : bufLen;
! 241: bufLen -= clen;
! 242:
! 243: do {
! 244: s1 += (u_short) *nBuf++;
! 245: s2 += s1;
! 246: } while (--clen);
! 247:
! 248: s1 = (s1 >> 8) + (s1 & 0xFF);
! 249: s2 = (s2 >> 8) + (s2 & 0xFF);
! 250: }
! 251:
! 252: crc_Errno ^= crc_Errno;
! 253: return (s2 << 8) | s1;
! 254: }
! 255:
! 256: /*
! 257: * crcFletcher() Fletcher-32 Checksum computing
! 258: * @nBuf = Data for calculation
! 259: * @bufLen = Length of data
! 260: * return: -1 error, !=-1 Checksum
! 261: */
! 262: inline u_int
! 263: crcFletcher(u_short * __restrict nBuf, int bufLen)
! 264: {
! 265: register u_int s1, s2, clen;
1.1 misho 266:
267: if (!nBuf) {
268: crc_Errno = 1;
269: strlcpy(crc_Error, "crcFletcher(): Invalid parameters!", MAX_STR + 1);
270: return -1;
271: }
272:
273: s1 = s2 = 0xFFFF;
274: while (bufLen) {
275: clen = bufLen > MAX_FLETCHER_DIGEST ? MAX_FLETCHER_DIGEST : bufLen;
276: bufLen -= clen;
277:
278: do {
1.2.2.1 ! misho 279: s1 += (u_int) *nBuf++;
1.1 misho 280: s2 += s1;
281: } while (--clen);
282:
283: s1 = (s1 >> 16) + (s1 & 0xFFFF);
284: s2 = (s2 >> 16) + (s2 & 0xFFFF);
285: }
286:
287: crc_Errno ^= crc_Errno;
288: return (s2 << 16) | s1;
289: }
290:
1.2 misho 291: /*
292: * crcAdler() crcAdler-32 Checksum computing
293: * @psBuf = Data for calculation
294: * @bufLen = Length of data
295: * return: -1 error, !=-1 Checksum
296: */
1.2.2.1 ! misho 297: inline u_int
! 298: crcAdler(u_char * __restrict psBuf, int bufLen)
1.1 misho 299: {
1.2.2.1 ! misho 300: register u_int s1, s2, clen;
1.1 misho 301:
302: if (!psBuf) {
303: crc_Errno = 1;
304: strlcpy(crc_Error, "crcAdler(): Invalid parameters!", MAX_STR + 1);
305: return -1;
306: }
307:
308: s1 = 1L;
309: s2 ^= s2;
310: while (bufLen) {
311: clen = bufLen > MAX_ADLER_DIGEST ? MAX_ADLER_DIGEST : bufLen;
312: bufLen -= clen;
313:
314: do {
1.2.2.1 ! misho 315: s1 += (u_int) *psBuf++;
1.1 misho 316: s2 += s1;
317: } while (--clen);
318:
319: s1 %= crc_modAdler;
320: s2 %= crc_modAdler;
321: }
322:
323: crc_Errno ^= crc_Errno;
324: return (s2 << 16) | s1;
325: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>