--- libelwix/src/crc.c	2013/01/17 10:05:35	1.1
+++ libelwix/src/crc.c	2017/12/08 00:07:13	1.4.18.1
@@ -3,7 +3,7 @@
 *  by Michael Pounov <misho@openbsd-bg.org>
 *
 * $Author: misho $
-* $Id: crc.c,v 1.1 2013/01/17 10:05:35 misho Exp $
+* $Id: crc.c,v 1.4.18.1 2017/12/08 00:07:13 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, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
+Copyright 2004 - 2015
 	by Michael Pounov <misho@elwix.org>.  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -75,12 +75,12 @@ const crcPoly_t crc_Poly[] = {
  * @crcBits = Number width bits 
  * return: -1 error, !=-1 reflecting number
  */
-inline u_int
+u_int
 crcReflect(u_int crcNum, u_char crcBits)
 {
-	register u_int i, j, rev;
+	register u_int i, j = 1, rev = 0;
 
-	for (i = (u_int) 1 << (crcBits - 1), j = 1, rev ^= rev; i; i >>= 1, j <<= 1)
+	for (i = (u_int) 1 << (crcBits - 1); i; i >>= 1, j <<= 1)
 		if (crcNum & i)
 			rev |= j;
 	return rev;
@@ -97,7 +97,7 @@ crcReflect(u_int crcNum, u_char crcBits)
  * @xorCRC = Last xor CRC value
  * return: -1 error, !=-1 CRC checksum
  */
-inline u_int
+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;
@@ -193,7 +193,7 @@ crcCalc(u_char * __restrict psBuf, u_int bufLen, u_cha
  * @bufLen = Length of data
  * return: -1 error, !=-1 Checksum
  */
-inline u_short
+u_short
 crcIP(u_char * __restrict buf, int bufLen)
 {
 	register u_int sum;
@@ -201,7 +201,7 @@ crcIP(u_char * __restrict buf, int bufLen)
 
 	assert(buf);
 
-	for (sum = 0; bufLen && bufLen > 1; bufLen -= 2)
+	for (sum = 0; bufLen > 1; bufLen -= 2)
 		sum += *nBuf++;
 	if (bufLen == 1) {
 		*(u_char*)(&last) += *(u_char*) nBuf;
@@ -215,13 +215,74 @@ crcIP(u_char * __restrict buf, int bufLen)
 }
 
 /*
+ * crcTCP() - Checksum for TCP v4 communication
+ *
+ * @buf = Data for calculation
+ * @bufLen = Length of data
+ * @th = TCP header
+ * return: -1 error, !=-1 Checksum
+ */
+u_short
+crcTCP(struct in_addr src, struct in_addr dst, u_char * __restrict th)
+{
+	struct psd_tcp {
+		struct in_addr src;
+		struct in_addr dst;
+		u_char pad;
+		u_char proto;
+		u_short tcp_len;
+		u_char tcp[20];
+	} buf;
+
+	buf.src = src;
+	buf.dst = dst;
+	buf.pad = 0;
+	buf.proto = IPPROTO_TCP;
+	buf.tcp_len = htons(sizeof buf.tcp);
+	memcpy(&buf.tcp, th, sizeof buf.tcp);
+
+	return crcIP((u_char*) &buf, sizeof buf);
+}
+
+/*
+ * crcUDP() - Checksum for UDP v4 communication
+ *
+ * @buf = Data for calculation
+ * @bufLen = Length of data
+ * @uh = UDP header
+ * return: -1 error, !=-1 Checksum
+ */
+u_short
+crcUDP(struct in_addr src, struct in_addr dst, u_char * __restrict uh)
+{
+	struct psd_udp {
+		struct in_addr src;
+		struct in_addr dst;
+		u_char pad;
+		u_char proto;
+		u_short udp_len;
+		u_char udp[8];
+	} buf;
+
+	buf.src = src;
+	buf.dst = dst;
+	buf.pad = 0;
+	buf.proto = IPPROTO_UDP;
+	buf.udp_len = htons(sizeof buf.udp);
+	memcpy(&buf.udp, uh, sizeof buf.udp);
+
+	return crcIP((u_char*) &buf, sizeof buf);
+}
+
+
+/*
  * crcFletcher16() - Fletcher-16 Checksum computing
  *
  * @nBuf = Data for calculation
  * @bufLen = Length of data
  * return: -1 error, !=-1 Checksum
  */
-inline u_short
+u_short
 crcFletcher16(u_short * __restrict nBuf, int bufLen)
 {
 	register u_short s1, s2;
@@ -253,7 +314,7 @@ crcFletcher16(u_short * __restrict nBuf, int bufLen)
  * @bufLen = Length of data
  * return: -1 error, !=-1 Checksum
  */
-inline u_int
+u_int
 crcFletcher(u_short * __restrict nBuf, int bufLen)
 {
 	register u_int s1, s2, clen;
@@ -284,15 +345,13 @@ crcFletcher(u_short * __restrict nBuf, int bufLen)
  * @bufLen = Length of data
  * return: -1 error, !=-1 Checksum
  */
-inline u_int
+u_int
 crcAdler(u_char * __restrict psBuf, int bufLen)
 {
-	register u_int s1, s2, clen;
+	register u_int s1 = 1, s2 = 0, clen;
 
 	assert(psBuf);
 
-	s1 = 1L;
-	s2 ^= s2;
 	while (bufLen) {
 		clen = bufLen > MAX_ADLER_DIGEST ? MAX_ADLER_DIGEST : bufLen;
 		bufLen -= clen;