--- libelwix/src/crc.c 2017/12/08 00:07:48 1.5 +++ libelwix/src/crc.c 2024/10/28 09:58:51 1.9 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: crc.c,v 1.5 2017/12/08 00:07:48 misho Exp $ +* $Id: crc.c,v 1.9 2024/10/28 09:58:51 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004 - 2015 +Copyright 2004 - 2024 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -46,6 +46,9 @@ SUCH DAMAGE. #include "global.h" +/* CRC16 poly */ +const u_short crc_16poly = 0x1021; + /* Adler module */ const u_int crc_modAdler = 0xFFF1L; @@ -56,7 +59,7 @@ const crcPoly_t crc_Poly[] = { { 5, (u_int) 0x15, "CRC-5-ITU" }, { 6, (u_int) 0x3, "CRC-6-ITU" }, { 7, (u_int) 0x9, "CRC-7-MMC" }, - { 8, (u_int) 0x8D, "CRC-8-CCITT" }, + { 8, (u_int) 0x7, "CRC-8-CCITT" }, { 10, (u_int) 0x233, "CRC-10" }, { 11, (u_int) 0x385, "CRC-11-FlexRay" }, { 12, (u_int) 0x80F, "CRC-12-Telco" }, @@ -64,7 +67,9 @@ const crcPoly_t crc_Poly[] = { { 16, (u_int) 0x8005, "CRC-16-IBM" }, { 24, (u_int) 0x864CFB, "CRC-24-Radix64" }, { 30, (u_int) 0x2030B9C7, "CRC-30-CDMA" }, - { 32, (u_int) 0x04C11DB7, "CRC-32-802.3" } + { 32, (u_int) 0x04C11DB7, "CRC-32-802.3" }, + { 16, (u_int) 0x1021, "CRC-16-CCITT" }, + { 16, (u_int) 0x8408, "CRC-16-XMODEM" } }; @@ -73,7 +78,7 @@ const crcPoly_t crc_Poly[] = { * * @crcNum = Number for reflection * @crcBits = Number width bits - * return: -1 error, !=-1 reflecting number + * return: reflecting number */ u_int crcReflect(u_int crcNum, u_char crcBits) @@ -95,12 +100,12 @@ crcReflect(u_int crcNum, u_char crcBits) * @RevOpts = Options for computation (REVOPTS_REVERTBYTE, REVOPTS_REVERTCRC) * @initCRC = Initial CRC value * @xorCRC = Last xor CRC value - * return: -1 error, !=-1 CRC checksum + * return: CRC checksum */ u_int crcCalc(u_char * __restrict psBuf, u_int bufLen, u_char crcBits, u_char RevOpts, u_int initCRC, u_int xorCRC) { - const u_int bits = sizeof(int) * 8 - crcBits; + u_int bits = sizeof(int) * 8; u_int poly, crchibit, crc; register u_int i, j, b, ch; @@ -109,46 +114,70 @@ crcCalc(u_char * __restrict psBuf, u_int bufLen, u_cha switch (crcBits) { case 1: poly = crc_Poly[0].poly_num; + bits -= crc_Poly[0].poly_bits; break; case 4: poly = crc_Poly[1].poly_num; + bits -= crc_Poly[1].poly_bits; break; case 5: poly = crc_Poly[2].poly_num; + bits -= crc_Poly[2].poly_bits; break; case 6: poly = crc_Poly[3].poly_num; + bits -= crc_Poly[3].poly_bits; break; case 7: poly = crc_Poly[4].poly_num; + bits -= crc_Poly[4].poly_bits; break; case 8: poly = crc_Poly[5].poly_num; + bits -= crc_Poly[5].poly_bits; break; case 10: poly = crc_Poly[6].poly_num; + bits -= crc_Poly[6].poly_bits; break; case 11: poly = crc_Poly[7].poly_num; + bits -= crc_Poly[7].poly_bits; break; case 12: poly = crc_Poly[8].poly_num; + bits -= crc_Poly[8].poly_bits; break; case 15: poly = crc_Poly[9].poly_num; + bits -= crc_Poly[9].poly_bits; break; case 16: poly = crc_Poly[10].poly_num; + bits -= crc_Poly[10].poly_bits; break; case 24: poly = crc_Poly[11].poly_num; + bits -= crc_Poly[11].poly_bits; break; case 30: poly = crc_Poly[12].poly_num; + bits -= crc_Poly[12].poly_bits; break; case 32: poly = crc_Poly[13].poly_num; + bits -= crc_Poly[13].poly_bits; break; + case 161: + poly = crc_Poly[14].poly_num; + bits -= crc_Poly[14].poly_bits; + crcBits = crc_Poly[14].poly_bits; + break; + case 162: + poly = crc_Poly[15].poly_num; + bits -= crc_Poly[15].poly_bits; + crcBits = crc_Poly[15].poly_bits; + break; default: elwix_SetErr(EINVAL, "crcCalc(): Unsupported CRC method!!!"); return -1; @@ -187,31 +216,90 @@ crcCalc(u_char * __restrict psBuf, u_int bufLen, u_cha /* - * crcIP() - Checksum in IP communication + * crc16_xy() - Checksum calculation in X/Y modem communication * * @buf = Data for calculation * @bufLen = Length of data - * return: -1 error, !=-1 Checksum + * return: Checksum */ u_short -crcIP(u_char * __restrict buf, int bufLen) +crc16_xy(u_char * __restrict buf, int bufLen) { - register u_int sum; - u_short last = 0, *nBuf = (u_short*) buf; + u_short crc, x; + register u_short i; assert(buf); - for (sum = 0; bufLen > 1; bufLen -= 2) - sum += *nBuf++; - if (bufLen == 1) { - *(u_char*)(&last) += *(u_char*) nBuf; - sum += last; + for (crc = 0; bufLen > 0; bufLen--, buf++) + for (i = 0x80; i; i >>= 1) { + x = crc >> 15; + crc <<= 1; + + if (*buf & i) + crc++; + if (x) + crc ^= crc_16poly; + } + + for (i = 0; i < 16; i++) { + x = crc >> 15; + crc <<= 1; + + if (x) + crc ^= crc_16poly; } + return crc; +} + +/* + * crc16_ccitt() - Checksum calculation + * + * @buf = Data for calculation + * @bufLen = Length of data + * return: Checksum + */ +u_short +crc16_ccitt(u_char * __restrict buf, int bufLen) +{ + u_short crc; + register u_char i; + + for (crc = 0; bufLen > 0; bufLen--, buf++) { + crc ^= (u_short) *buf << 8; + for (i = 0x80; i; i >>= 1) + if (crc & 0x8000) + crc = crc << 1 ^ crc_16poly; + else + crc <<= 1; + } + + return crc; +} + +/* + * crcIP() - Checksum in IP communication + * + * @buf = Data for calculation + * @len = Length of data in bytes + * return: Checksum + */ +u_short +crcIP(u_short* __restrict buf, int len) +{ + register u_long sum = 0; + + assert(buf); + + for (sum = 0; len > 1; len -= 2) + sum += *buf++; + if (len > 0) + sum += ((*buf) & htons(0xFF00)); + sum = (sum >> 16) + (sum & 0xFFFF); sum += sum >> 16; - return (u_short) ~sum; + return (u_short) (~sum); } /* @@ -220,7 +308,7 @@ crcIP(u_char * __restrict buf, int bufLen) * @buf = Data for calculation * @bufLen = Length of data * @th = TCP header - * return: -1 error, !=-1 Checksum + * return: Checksum */ u_short crcTCP(struct in_addr src, struct in_addr dst, u_char * __restrict th) @@ -241,7 +329,7 @@ crcTCP(struct in_addr src, struct in_addr dst, u_char buf.tcp_len = htons(sizeof buf.tcp); memcpy(&buf.tcp, th, sizeof buf.tcp); - return crcIP((u_char*) &buf, sizeof buf); + return crcIP((u_short*) &buf, sizeof buf); } /* @@ -250,7 +338,7 @@ crcTCP(struct in_addr src, struct in_addr dst, u_char * @buf = Data for calculation * @bufLen = Length of data * @uh = UDP header - * return: -1 error, !=-1 Checksum + * return: Checksum */ u_short crcUDP(struct in_addr src, struct in_addr dst, u_char * __restrict uh) @@ -271,7 +359,7 @@ crcUDP(struct in_addr src, struct in_addr dst, u_char buf.udp_len = htons(sizeof buf.udp); memcpy(&buf.udp, uh, sizeof buf.udp); - return crcIP((u_char*) &buf, sizeof buf); + return crcIP((u_short*) &buf, sizeof buf); } @@ -280,7 +368,7 @@ crcUDP(struct in_addr src, struct in_addr dst, u_char * * @nBuf = Data for calculation * @bufLen = Length of data - * return: -1 error, !=-1 Checksum + * return: Checksum */ u_short crcFletcher16(u_short * __restrict nBuf, int bufLen) @@ -312,7 +400,7 @@ crcFletcher16(u_short * __restrict nBuf, int bufLen) * * @nBuf = Data for calculation * @bufLen = Length of data - * return: -1 error, !=-1 Checksum + * return: Checksum */ u_int crcFletcher(u_short * __restrict nBuf, int bufLen) @@ -343,7 +431,7 @@ crcFletcher(u_short * __restrict nBuf, int bufLen) * * @psBuf = Data for calculation * @bufLen = Length of data - * return: -1 error, !=-1 Checksum + * return: Checksum */ u_int crcAdler(u_char * __restrict psBuf, int bufLen)