--- libelwix/src/crc.c	2024/10/12 16:07:17	1.7.4.1
+++ libelwix/src/crc.c	2024/10/29 01:22:08	1.9.4.1
@@ -3,7 +3,7 @@
 *  by Michael Pounov <misho@openbsd-bg.org>
 *
 * $Author: misho $
-* $Id: crc.c,v 1.7.4.1 2024/10/12 16:07:17 misho Exp $
+* $Id: crc.c,v 1.9.4.1 2024/10/29 01:22:08 misho Exp $
 *
 **************************************************************************
 The ELWIX and AITNET software is distributed under the following
@@ -281,28 +281,25 @@ crc16_ccitt(u_char * __restrict buf, int bufLen)
  * crcIP() - Checksum in IP communication
  *
  * @buf = Data for calculation
- * @bufLen = Length of data
+ * @len = Length of data in bytes
  * return: Checksum
  */
 u_short
-crcIP(u_char * __restrict buf, int bufLen)
+crcIP(u_short* __restrict buf, int len)
 {
-	register u_int sum;
-	u_short last = 0, *nBuf = (u_short*) buf;
+	register u_long sum = 0;
 
 	assert(buf);
 
-	for (sum = 0; bufLen > 1; bufLen -= 2)
-		sum += *nBuf++;
-	if (bufLen == 1) {
-		*(u_char*)(&last) += *(u_char*) nBuf;
-		sum += last;
-	}
+	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);
 }
 
 /*
@@ -316,6 +313,8 @@ crcIP(u_char * __restrict buf, int bufLen)
 u_short
 crcTCP(struct in_addr src, struct in_addr dst, u_char * __restrict th)
 {
+	assert(th);
+
 	struct psd_tcp {
 		struct in_addr src;
 		struct in_addr dst;
@@ -332,7 +331,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);
 }
 
 /*
@@ -346,6 +345,8 @@ crcTCP(struct in_addr src, struct in_addr dst, u_char 
 u_short
 crcUDP(struct in_addr src, struct in_addr dst, u_char * __restrict uh)
 {
+	assert(uh);
+
 	struct psd_udp {
 		struct in_addr src;
 		struct in_addr dst;
@@ -362,7 +363,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);
 }