--- libelwix/src/crc.c	2017/12/08 00:07:13	1.4.18.1
+++ libelwix/src/crc.c	2024/10/12 16:07:17	1.7.4.1
@@ -3,7 +3,7 @@
 *  by Michael Pounov <misho@openbsd-bg.org>
 *
 * $Author: misho $
-* $Id: crc.c,v 1.4.18.1 2017/12/08 00:07:13 misho Exp $
+* $Id: crc.c,v 1.7.4.1 2024/10/12 16:07:17 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 <info@elwix.org>
 
-Copyright 2004 - 2015
+Copyright 2004 - 2024
 	by Michael Pounov <misho@elwix.org>.  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,11 +216,73 @@ crcCalc(u_char * __restrict psBuf, u_int bufLen, u_cha
 
 
 /*
+ * crc16_xy() - Checksum calculation in X/Y modem communication
+ *
+ * @buf = Data for calculation
+ * @bufLen = Length of data
+ * return: Checksum
+ */
+u_short
+crc16_xy(u_char * __restrict buf, int bufLen)
+{
+	u_short crc, x;
+	register u_short i;
+
+	assert(buf);
+
+	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
  * @bufLen = Length of data
- * return: -1 error, !=-1 Checksum
+ * return: Checksum
  */
 u_short
 crcIP(u_char * __restrict buf, int bufLen)
@@ -220,7 +311,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)
@@ -250,7 +341,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)
@@ -280,7 +371,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 +403,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 +434,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)