Annotation of libelwix/src/crc.c, revision 1.3
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.3 ! misho 6: * $Id: crc.c,v 1.2.12.1 2014/01/29 14:11:45 misho Exp $
1.1 misho 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:
1.3 ! misho 15: Copyright 2004 - 2014
1.1 misho 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: {
1.2 misho 81: register u_int i, j = 1, rev = 0;
1.1 misho 82:
1.2 misho 83: for (i = (u_int) 1 << (crcBits - 1); i; i >>= 1, j <<= 1)
1.1 misho 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: {
1.2 misho 290: register u_int s1 = 1, s2 = 0, clen;
1.1 misho 291:
292: assert(psBuf);
293:
294: while (bufLen) {
295: clen = bufLen > MAX_ADLER_DIGEST ? MAX_ADLER_DIGEST : bufLen;
296: bufLen -= clen;
297:
298: do {
299: s1 += (u_int) *psBuf++;
300: s2 += s1;
301: } while (--clen);
302:
303: s1 %= crc_modAdler;
304: s2 %= crc_modAdler;
305: }
306:
307: return (s2 << 16) | s1;
308: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>