Livt packages

Livt.Net

Version 1.4.1

Ethernet, IPv4, TCP, UDP, ARP, TFTP, and Telnet networking components for Livt hardware.

Published files (163)

src/tcp/TcpChecksum.lvt

namespace Livt.Net

/**
 * Pure IPv4/TCP pseudo-header and fixed-header checksum calculation.
 * All arrays contain network-order octets; no scheduled component is required.
 */
class TcpChecksum
{
	/**
	 * Calculates a checksum for a fixed 20-byte TCP header without payload.
	 * Sequence, acknowledgment, flags and window describe the emitted header.
	 */
	public static inline fn CalculateFixedHeaderChecksum[](
		sourceIp: byte[4], destinationIp: byte[4],
		sourcePort: byte[2], destinationPort: byte[2],
		sequence: byte[4], acknowledgment: byte[4], flags: byte, window: byte[2]) int
	{
		return TcpChecksum.CalculatePayloadChecksum(sourceIp, destinationIp,
			sourcePort, destinationPort, sequence, acknowledgment, flags, window, 20, 0)
	}

	/**
	 * Calculates a checksum including the supplied unfolded payloadWordSum from
	 * InternetChecksum.GetWordSum(). tcpLength is 20..65515 including the fixed
	 * header. Odd payloads include a zero low octet in their last word. The complete
	 * sum must fit a non-negative int (at most 2147483647); caller validates bounds.
	 */
	public static inline fn CalculatePayloadChecksum[](
		sourceIp: byte[4], destinationIp: byte[4],
		sourcePort: byte[2], destinationPort: byte[2],
		sequence: byte[4], acknowledgment: byte[4], flags: byte, window: byte[2],
		tcpLength: int, payloadWordSum: int) int
	{
		// Balanced groups avoid a long serial carry chain through every header word.
		var sourceSum = NetworkOrder.Word(sourceIp[0], sourceIp[1])
			+ NetworkOrder.Word(sourceIp[2], sourceIp[3])
		var destinationSum = NetworkOrder.Word(destinationIp[0], destinationIp[1])
			+ NetworkOrder.Word(destinationIp[2], destinationIp[3])
		var sequenceSum = NetworkOrder.Word(sequence[0], sequence[1])
			+ NetworkOrder.Word(sequence[2], sequence[3])
		var acknowledgmentSum = NetworkOrder.Word(acknowledgment[0], acknowledgment[1])
			+ NetworkOrder.Word(acknowledgment[2], acknowledgment[3])
		var portSum = NetworkOrder.Word(sourcePort[0], sourcePort[1])
			+ NetworkOrder.Word(destinationPort[0], destinationPort[1])
		var controlSum = 0x5000 + NetworkOrder.ByteValue(flags)
			+ NetworkOrder.Word(window[0], window[1])
		var pseudoSum = NetworkOrder.ByteValue(IIpv4Payload.PROTOCOL_TCP) + tcpLength
		var addressSum = sourceSum + destinationSum
		var positionSum = sequenceSum + acknowledgmentSum
		var transportSum = portSum + controlSum
		var headerSum = (addressSum + positionSum) + (transportSum + pseudoSum)
		var sum = headerSum + payloadWordSum
		return ChecksumArithmetic.Finish(sum)
	}
}