From 9e80202352dd49bdd9e67b8b906d86f058431505 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineering.com>
Date: Sat, 11 May 2019 15:12:49 -0500
Subject: Initial import of abandoned HQEMU version 2.5.2

---
 src/roms/openbios/libopenbios/ipchecksum.c | 55 ++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 src/roms/openbios/libopenbios/ipchecksum.c

(limited to 'src/roms/openbios/libopenbios/ipchecksum.c')

diff --git a/src/roms/openbios/libopenbios/ipchecksum.c b/src/roms/openbios/libopenbios/ipchecksum.c
new file mode 100644
index 0000000..83f39bc
--- /dev/null
+++ b/src/roms/openbios/libopenbios/ipchecksum.c
@@ -0,0 +1,55 @@
+/* Taken from Etherboot */
+
+#include "libopenbios/ipchecksum.h"
+
+unsigned short ipchksum(const void *data, unsigned long length)
+{
+	unsigned long sum;
+	unsigned long i;
+	const unsigned char *ptr;
+	union {
+	    unsigned char byte[2];
+	    unsigned short word;
+	} u;
+
+	/* In the most straight forward way possible,
+	 * compute an ip style checksum.
+	 */
+	sum = 0;
+	ptr = data;
+	for(i = 0; i < length; i++) {
+		unsigned long value;
+		value = ptr[i];
+		if (i & 1) {
+			value <<= 8;
+		}
+		/* Add the new value */
+		sum += value;
+		/* Wrap around the carry */
+		if (sum > 0xFFFF) {
+			sum = (sum + (sum >> 16)) & 0xFFFF;
+		}
+	}
+	u.byte[0] = (unsigned char) sum;
+	u.byte[1] = (unsigned char) (sum >> 8);
+	return (unsigned short) ~u.word;
+}
+
+unsigned short add_ipchksums(unsigned long offset, unsigned short sum, unsigned short new)
+{
+	unsigned long checksum;
+	sum = ~sum & 0xFFFF;
+	new = ~new & 0xFFFF;
+	if (offset & 1) {
+		/* byte swap the sum if it came from an odd offset
+		 * since the computation is endian independant this
+		 * works.
+		 */
+		new = (new << 8) | (new >> 8);
+	}
+	checksum = sum + new;
+	if (checksum > 0xFFFF) {
+		checksum -= 0xFFFF;
+	}
+	return (~checksum) & 0xFFFF;
+}
-- 
cgit v1.1