Annotation of libaitcrc/src/aitcrc.c, revision 1.2
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 ! misho 6: * $Id: aitcrc.c,v 1.1.1.1.2.1 2008/11/05 17:35:20 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.1 misho 16: const u_long crc_modAdler = 0xFFF1L;
17:
1.2 ! 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.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.1 misho 74: inline u_long crcReflect(u_long crcNum, u_char crcBits)
75: {
76: register u_long i, j, rev;
77:
78: for (i = (u_long) 1 << (crcBits - 1), j = 1, rev ^= rev; i; i >>= 1, j <<= 1)
79: if (crcNum & i)
80: rev |= j;
81:
82: crc_Errno ^= crc_Errno;
83: return rev;
84: }
85:
1.2 ! misho 86: /*
! 87: * crcCalc() Generic CRC calculation function for many sub variants of CRC algorithms
! 88: * @psBuf = Data for calculation
! 89: * @bufLen = Length of data
! 90: * @crcBits = CRC algorithm bits (1, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 24, 30, 32)
! 91: * @RevOpts = Options for computation (REVOPTS_REVERTBYTE, REVOPTS_REVERTCRC)
! 92: * @initCRC = Initial CRC value
! 93: * @xorCRC = Last xor CRC value
! 94: * return: -1 error, !=-1 CRC checksum
! 95: */
1.1 misho 96: inline u_long crcCalc(u_char * __restrict psBuf, u_int bufLen, u_char crcBits, u_char RevOpts, u_long initCRC, u_long xorCRC)
97: {
98: const u_long bits = sizeof(long) * 8 - crcBits;
99: u_long poly, crchibit, crc;
100: register u_long i, j, b, ch;
101:
102: if (!psBuf) {
103: crc_Errno = 1;
104: strlcpy(crc_Error, "crcCalc(): Invalid parameters!", MAX_STR + 1);
105: return -1;
106: }
107:
108: switch (crcBits) {
109: case 1:
110: poly = crc_Poly[0].poly_num;
111: break;
112: case 4:
113: poly = crc_Poly[1].poly_num;
114: break;
115: case 5:
116: poly = crc_Poly[2].poly_num;
117: break;
118: case 6:
119: poly = crc_Poly[3].poly_num;
120: break;
121: case 7:
122: poly = crc_Poly[4].poly_num;
123: break;
124: case 8:
125: poly = crc_Poly[5].poly_num;
126: break;
127: case 10:
128: poly = crc_Poly[6].poly_num;
129: break;
130: case 11:
131: poly = crc_Poly[7].poly_num;
132: break;
133: case 12:
134: poly = crc_Poly[8].poly_num;
135: break;
136: case 15:
137: poly = crc_Poly[9].poly_num;
138: break;
139: case 16:
140: poly = crc_Poly[10].poly_num;
141: break;
142: case 24:
143: poly = crc_Poly[11].poly_num;
144: break;
145: case 30:
146: poly = crc_Poly[12].poly_num;
147: break;
148: case 32:
149: poly = crc_Poly[13].poly_num;
150: break;
151: default:
152: crc_Errno = 2;
153: strlcpy(crc_Error, "crcCalc(): Unsupported CRC method!!!", MAX_STR + 1);
154: return -1;
155: }
156: poly <<= bits;
157:
158: crchibit = (u_long) 1 << (crcBits - 1);
159: crchibit <<= bits;
160: crc = initCRC << bits;
161:
162: for (i = 0; i < bufLen; i++) {
163: ch = (u_long) *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(long) * 8);
180: crc ^= xorCRC << bits;
181: crc &= (((crchibit - 1) << 1) | 1);
182: if (!(RevOpts & REVOPTS_REVERTCRC))
183: crc >>= bits;
184:
185: crc_Errno ^= crc_Errno;
186: return crc;
187: }
188:
189: // ----------------------------------------------------------
190:
1.2 ! misho 191: /*
! 192: * crcIP() Checksum in IP communication
! 193: * @nBuf = Data for calculation
! 194: * @bufLen = Length of data
! 195: * return: -1 error, !=-1 Checksum
! 196: */
1.1 misho 197: inline u_short crcIP(u_short * __restrict nBuf, int bufLen)
198: {
199: register u_long sum;
200:
201: if (!nBuf) {
202: crc_Errno = 1;
203: strlcpy(crc_Error, "crcIP(): Invalid parameters!", MAX_STR + 1);
204: return -1;
205: }
206:
207: for (sum = 0; bufLen; bufLen--)
208: sum += *nBuf++;
209:
210: sum = (sum >> 16) + (sum & 0xFFFF);
211: sum += sum >> 16;
212:
213: crc_Errno ^= crc_Errno;
214: return (u_short) ~sum;
215: }
216:
1.2 ! misho 217: /*
! 218: * crcFletcher() Fletcher-16 Checksum computing
! 219: * @nBuf = Data for calculation
! 220: * @bufLen = Length of data
! 221: * return: -1 error, !=-1 Checksum
! 222: */
1.1 misho 223: inline u_long crcFletcher(u_short * __restrict nBuf, int bufLen)
224: {
225: register u_long s1, s2, clen;
226:
227: if (!nBuf) {
228: crc_Errno = 1;
229: strlcpy(crc_Error, "crcFletcher(): Invalid parameters!", MAX_STR + 1);
230: return -1;
231: }
232:
233: s1 = s2 = 0xFFFF;
234: while (bufLen) {
235: clen = bufLen > MAX_FLETCHER_DIGEST ? MAX_FLETCHER_DIGEST : bufLen;
236: bufLen -= clen;
237:
238: do {
239: s1 += (u_long) *nBuf++;
240: s2 += s1;
241: } while (--clen);
242:
243: s1 = (s1 >> 16) + (s1 & 0xFFFF);
244: s2 = (s2 >> 16) + (s2 & 0xFFFF);
245: }
246:
247: crc_Errno ^= crc_Errno;
248: return (s2 << 16) | s1;
249: }
250:
1.2 ! misho 251: /*
! 252: * crcAdler() crcAdler-32 Checksum computing
! 253: * @psBuf = Data for calculation
! 254: * @bufLen = Length of data
! 255: * return: -1 error, !=-1 Checksum
! 256: */
1.1 misho 257: inline u_long crcAdler(u_char * __restrict psBuf, int bufLen)
258: {
259: register u_long s1, s2, clen;
260:
261: if (!psBuf) {
262: crc_Errno = 1;
263: strlcpy(crc_Error, "crcAdler(): Invalid parameters!", MAX_STR + 1);
264: return -1;
265: }
266:
267: s1 = 1L;
268: s2 ^= s2;
269: while (bufLen) {
270: clen = bufLen > MAX_ADLER_DIGEST ? MAX_ADLER_DIGEST : bufLen;
271: bufLen -= clen;
272:
273: do {
274: s1 += (u_long) *psBuf++;
275: s2 += s1;
276: } while (--clen);
277:
278: s1 %= crc_modAdler;
279: s2 %= crc_modAdler;
280: }
281:
282: crc_Errno ^= crc_Errno;
283: return (s2 << 16) | s1;
284: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>