Livt packages

Livt.Net

Version 1.4.1

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

Published files (163)

tests/TcpSegmentTest.lvt

namespace Livt.Net.Tests
using Livt.Net

/** Prepared TCP regression vectors calculated independently from the wire format. */
@Test
component TcpSegmentTest
{
	data: ArrayPacketData<64>
	tcp: TcpSegment<ArrayPacketData<64>>
	packet: TcpIpv4Packet<ArrayPacketData<64>>
	frame: TcpIpv4Frame<ArrayPacketData<64>>
	fault: FaultingFrameData
	faultTcp: TcpSegment<FaultingFrameData>
	new()
	{
		this.data = new ArrayPacketData<64>()
		this.tcp = new TcpSegment<ArrayPacketData<64>>(this.data)
		this.packet = new TcpIpv4Packet<ArrayPacketData<64>>(this.tcp)
		this.frame = new TcpIpv4Frame<ArrayPacketData<64>>(this.packet)
		this.fault = new FaultingFrameData()
		this.faultTcp = new TcpSegment<FaultingFrameData>(this.fault)
	}

	fn Clean()
	{
		this.frame.Invalidate()
		this.packet.Invalidate()
		this.tcp.Invalidate()

		if (this.data.IsReady()) {
			this.data.TryRelease()
		}
		else {
			this.data.TryClear()
		}
	}

	fn Prepare() PacketDataResult
	{
		var sourceIp: byte[4] = [0xC0, 0xA8, 0x01, 0x80]
		var destinationIp: byte[4] = [0xC0, 0xA8, 0x01, 0xFF]
		var sourcePort: byte[2] = [0x00, 0x50]
		var destinationPort: byte[2] = [0xC0, 0x81]
		var sequence: byte[4] = [0x80, 0x12, 0x34, 0xFF]
		var ack: byte[4] = [0xFE, 0xDC, 0xBA, 0x98]
		var window: byte[2] = [0x81, 0x23]
		var id: byte[2] = [0x00, 0x02]
		var sourceMac: byte[6] = [0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]
		var destinationMac: byte[6] = [0x82, 0x10, 0x20, 0x30, 0x40, 0xFE]
		var result = this.tcp.TryPrepare(sourceIp, destinationIp, sourcePort, destinationPort, sequence, ack, 0x12, window)

		if (result != PacketDataResult.Success) {
			return result
		}

		result = this.packet.TryPrepare(sourceIp, destinationIp, id)

		if (result != PacketDataResult.Success) {
			return result
		}

		return this.frame.TryPrepare(sourceMac, destinationMac)
	}

	@Test
	fn EmptySynAck()
	{
		this.Clean()
		var value: byte = 0xFF
		assert this.tcp.TryRead(0, value) == PacketDataResult.NotReady
		assert this.data.TryPublish() == PacketDataResult.Success
		assert this.Prepare() == PacketDataResult.Success
		assert this.frame.GetAvailableLength() == 60
		assert this.tcp.GetAvailableLength() == 20
		var expected: byte[60] = [0x82, 0x10, 0x20, 0x30, 0x40, 0xFE, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x00, 0x02, 0x40, 0x00, 0x40, 0x06, 0xB5, 0xFE, 0xC0, 0xA8, 0x01, 0x80, 0xC0, 0xA8, 0x01, 0xFF, 0x00, 0x50, 0xC0, 0x81, 0x80, 0x12, 0x34, 0xFF, 0xFE, 0xDC, 0xBA, 0x98, 0x50, 0x12, 0x81, 0x23, 0x7A, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

		for (var i = 0; i < 60; i++) {
			assert this.frame.TryRead(i, value) == PacketDataResult.Success
			assert value == expected[i]
		}

		assert this.frame.TryRead(-1, value) == PacketDataResult.Invalid
		assert this.frame.TryRead(60, value) == PacketDataResult.Invalid
		this.Clean()
	}

	@Test
	fn OddHighBitPayload()
	{
		this.Clean()
		var value: byte = 0xFF
		assert this.tcp.TryRead(0, value) == PacketDataResult.NotReady
		assert this.data.TryWrite(0, 0xFF) == PacketDataResult.Success
		assert this.data.TryWrite(1, 0x80) == PacketDataResult.Success
		assert this.data.TryWrite(2, 0x81) == PacketDataResult.Success
		assert this.data.TryPublish() == PacketDataResult.Success
		assert this.Prepare() == PacketDataResult.Success
		assert this.frame.GetAvailableLength() == 60
		assert this.tcp.GetAvailableLength() == 23
		var expected: byte[60] = [0x82, 0x10, 0x20, 0x30, 0x40, 0xFE, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2B, 0x00, 0x02, 0x40, 0x00, 0x40, 0x06, 0xB5, 0xFB, 0xC0, 0xA8, 0x01, 0x80, 0xC0, 0xA8, 0x01, 0xFF, 0x00, 0x50, 0xC0, 0x81, 0x80, 0x12, 0x34, 0xFF, 0xFE, 0xDC, 0xBA, 0x98, 0x50, 0x12, 0x81, 0x23, 0xFA, 0x01, 0x00, 0x00, 0xFF, 0x80, 0x81, 0x00, 0x00, 0x00]

		for (var i = 0; i < 60; i++) {
			assert this.frame.TryRead(i, value) == PacketDataResult.Success
			assert value == expected[i]
		}

		assert this.frame.TryRead(-1, value) == PacketDataResult.Invalid
		assert this.frame.TryRead(60, value) == PacketDataResult.Invalid
		this.Clean()
	}

	@Test
	fn EvenPayload()
	{
		this.Clean()
		var value: byte = 0xFF
		assert this.tcp.TryRead(0, value) == PacketDataResult.NotReady
		assert this.data.TryWrite(0, 0x00) == PacketDataResult.Success
		assert this.data.TryWrite(1, 0xFF) == PacketDataResult.Success
		assert this.data.TryWrite(2, 0x80) == PacketDataResult.Success
		assert this.data.TryWrite(3, 0x01) == PacketDataResult.Success
		assert this.data.TryPublish() == PacketDataResult.Success
		assert this.Prepare() == PacketDataResult.Success
		assert this.frame.GetAvailableLength() == 60
		assert this.tcp.GetAvailableLength() == 24
		var expected: byte[60] = [0x82, 0x10, 0x20, 0x30, 0x40, 0xFE, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2C, 0x00, 0x02, 0x40, 0x00, 0x40, 0x06, 0xB5, 0xFA, 0xC0, 0xA8, 0x01, 0x80, 0xC0, 0xA8, 0x01, 0xFF, 0x00, 0x50, 0xC0, 0x81, 0x80, 0x12, 0x34, 0xFF, 0xFE, 0xDC, 0xBA, 0x98, 0x50, 0x12, 0x81, 0x23, 0xF9, 0x81, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x01, 0x00, 0x00]

		for (var i = 0; i < 60; i++) {
			assert this.frame.TryRead(i, value) == PacketDataResult.Success
			assert value == expected[i]
		}

		assert this.frame.TryRead(-1, value) == PacketDataResult.Invalid
		assert this.frame.TryRead(60, value) == PacketDataResult.Invalid
		this.Clean()
	}

	fn PrepareFault() PacketDataResult
	{
		var ip: byte[4] = [0xFF, 0xFF, 0xFF, 0xFF]
		var port: byte[2] = [0xFF, 0xFF]
		var sequence: byte[4] = [0xFF, 0xFF, 0xFF, 0xFF]
		return this.faultTcp.TryPrepare(ip, ip, port, port, sequence, sequence, 0xFF, port)
	}

	@Test
	fn ChecksBoundsFailuresAndCachedHeader()
	{
		this.faultTcp.Invalidate()
		this.fault.Configure(-1, -1)
		assert this.PrepareFault() == PacketDataResult.Invalid
		assert this.fault.GetReadCount() == 0
		this.fault.Configure(65495, 0)
		assert this.PrepareFault() == PacketDataResult.Invalid
		assert this.fault.GetReadCount() == 1
		this.fault.Configure(65496, -1)
		assert this.PrepareFault() == PacketDataResult.Invalid
		assert this.fault.GetReadCount() == 0
		this.fault.Configure(3, 1)
		assert this.PrepareFault() == PacketDataResult.Invalid
		assert !this.faultTcp.IsReady()
		assert this.faultTcp.GetAvailableLength() == 0
		this.fault.Configure(3, -1)
		assert this.PrepareFault() == PacketDataResult.Success
		assert this.fault.GetReadCount() == 3
		var value: byte = 0x00
		assert this.faultTcp.TryRead(16, value) == PacketDataResult.Success
		assert this.fault.GetReadCount() == 3
		// Inject a downstream fault to check propagation (external lifetime violation).
		this.fault.Configure(3, 2)
		assert this.faultTcp.TryRead(22, value) == PacketDataResult.Invalid
		assert this.PrepareFault() == PacketDataResult.Invalid
		assert this.faultTcp.TryRead(0, value) == PacketDataResult.NotReady
	}
}