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/ArpResponderTest.lvt

namespace Livt.Net.Tests

using Livt.Net

/**
 * Owns request storage and a responder; request setup invalidates replies before replacing input.
 */
@Test
component ArpResponderTest
{
	// Shared request parsers; source remains owned by this fixture.
	ethernet: EthernetFrameParser<ArrayPacketData<64>>

	data: ArrayPacketData<64>
	responder: ArpResponder<ArrayPacketData<64>>

	/**
	 * Binds the responder to owned request storage; request setup controls publication.
	 */
	new()
	{
		data = new ArrayPacketData<64>()
		this.ethernet = new EthernetFrameParser<ArrayPacketData<64>>(data)
		responder = new ArpResponder<ArrayPacketData<64>>(this.ethernet)
	}

	/**
	 * Prepares an independently initialized request and checks reply bytes or rejection behavior.
	 */
	@Test
	fn RespondsOnlyToLocalIpv4Request()
	{
		var request: byte[64]
		request[12] = 0x08
		request[13] = 0x06
		var arpEthernetIpv4Request: byte[8]
		arpEthernetIpv4Request[0] = 0x00
		arpEthernetIpv4Request[1] = 0x01
		arpEthernetIpv4Request[2] = 0x08
		arpEthernetIpv4Request[3] = 0x00
		arpEthernetIpv4Request[4] = 0x06
		arpEthernetIpv4Request[5] = 0x04
		arpEthernetIpv4Request[6] = 0x00
		arpEthernetIpv4Request[7] = 0x01
		var localIp: byte[4]
		localIp[0] = 0x0A
		localIp[1] = 0x00
		localIp[2] = 0x00
		localIp[3] = 0x01
		var wrongIp: byte[4]
		wrongIp[0] = 0x0A
		wrongIp[1] = 0x00
		wrongIp[2] = 0x00
		wrongIp[3] = 0x02

		request[14] = arpEthernetIpv4Request[0]
		request[15] = arpEthernetIpv4Request[1]
		request[16] = arpEthernetIpv4Request[2]
		request[17] = arpEthernetIpv4Request[3]
		request[18] = arpEthernetIpv4Request[4]
		request[19] = arpEthernetIpv4Request[5]
		request[20] = arpEthernetIpv4Request[6]
		request[21] = arpEthernetIpv4Request[7]
		request[38] = localIp[0]
		request[39] = localIp[1]
		request[40] = localIp[2]
		request[41] = localIp[3]

		assert (this.PrepareRequest(request, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00], localIp, 64) == PacketDataResult.Success) == true
		assert (this.PrepareRequest(request, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00], wrongIp, 64) == PacketDataResult.Success) == false
	}

	/**
	 * Prepares an independently initialized request and checks reply bytes or rejection behavior.
	 */
	@Test
	fn BuildsArpReplyBytes()
	{
		var request: byte[64]
		request[12] = 0x08
		request[13] = 0x06
		var localMac: byte[6]
		localMac[0] = 0x02
		localMac[1] = 0x55
		localMac[2] = 0x66
		localMac[3] = 0x77
		localMac[4] = 0x11
		localMac[5] = 0x22
		var localIp: byte[4]
		localIp[0] = 0x0A
		localIp[1] = 0x00
		localIp[2] = 0x00
		localIp[3] = 0x01
		var senderMac: byte[6]
		senderMac[0] = 0x02
		senderMac[1] = 0x10
		senderMac[2] = 0x20
		senderMac[3] = 0x30
		senderMac[4] = 0x40
		senderMac[5] = 0x50
		var senderIp: byte[4]
		senderIp[0] = 0x0A
		senderIp[1] = 0x00
		senderIp[2] = 0x00
		senderIp[3] = 0x02

		request[22] = senderMac[0]
		request[23] = senderMac[1]
		request[24] = senderMac[2]
		request[25] = senderMac[3]
		request[26] = senderMac[4]
		request[27] = senderMac[5]
		request[28] = senderIp[0]
		request[29] = senderIp[1]
		request[30] = senderIp[2]
		request[31] = senderIp[3]

		request[12] = 0x08
		request[13] = 0x06
		request[14] = 0x00
		request[15] = 0x01
		request[16] = 0x08
		request[17] = 0x00
		request[18] = 0x06
		request[19] = 0x04
		request[20] = 0x00
		request[21] = 0x01

		for (var j = 0; j < 4; j++) {
			request[38 + j] = localIp[j]
		}

		assert this.PrepareRequest(request, localMac, localIp, 64) == PacketDataResult.Success
		var responderByte: byte = 0x00
		assert this.responder.TryRead(0, responderByte) == PacketDataResult.Success
		assert responderByte == 0x02
		assert this.responder.TryRead(5, responderByte) == PacketDataResult.Success
		assert responderByte == 0x50
		assert this.responder.TryRead(6, responderByte) == PacketDataResult.Success
		assert responderByte == 0x02
		assert this.responder.TryRead(11, responderByte) == PacketDataResult.Success
		assert responderByte == 0x22
		assert this.responder.TryRead(12, responderByte) == PacketDataResult.Success
		assert responderByte == 0x08
		assert this.responder.TryRead(13, responderByte) == PacketDataResult.Success
		assert responderByte == 0x06
		assert this.responder.TryRead(21, responderByte) == PacketDataResult.Success
		assert responderByte == 0x02
		assert this.responder.TryRead(22, responderByte) == PacketDataResult.Success
		assert responderByte == 0x02
		assert this.responder.TryRead(27, responderByte) == PacketDataResult.Success
		assert responderByte == 0x22
		assert this.responder.TryRead(28, responderByte) == PacketDataResult.Success
		assert responderByte == 0x0A
		assert this.responder.TryRead(31, responderByte) == PacketDataResult.Success
		assert responderByte == 0x01
		assert this.responder.TryRead(32, responderByte) == PacketDataResult.Success
		assert responderByte == 0x02
		assert this.responder.TryRead(37, responderByte) == PacketDataResult.Success
		assert responderByte == 0x50
		assert this.responder.TryRead(38, responderByte) == PacketDataResult.Success
		assert responderByte == 0x0A
		assert this.responder.TryRead(41, responderByte) == PacketDataResult.Success
		assert responderByte == 0x02
	}

	/**
	 * Prepares an independently initialized request and checks reply bytes or rejection behavior.
	 */
	@Test
	fn SnapshotsAddressesAndClearsRejectedRequest()
	{
		var request: byte[64]
		request[12] = 0x08
		request[13] = 0x06
		var mac: byte[6] = [0x02, 0x55, 0x66, 0x77, 0x11, 0x22]
		var ip: byte[4] = [0x0A, 0x00, 0x00, 0x01]
		var value: byte = 0x00
		request[12] = 0x08
		request[13] = 0x06
		request[14] = 0x00
		request[15] = 0x01
		request[16] = 0x08
		request[17] = 0x00
		request[18] = 0x06
		request[19] = 0x04
		request[20] = 0x00
		request[21] = 0x01
		request[22] = 0x82

		for (var i = 0; i < 4; i++) {
			request[38 + i] = ip[i]
		}

		assert this.PrepareRequest(request, mac, ip, 42) == PacketDataResult.Success
		request[22] = 0x01

		// Success closed all input views; reuse the actual provider independently.
		assert data.TryRelease() == PacketDataResult.Success
		assert data.TryWrite(0, 0xEE) == PacketDataResult.Success
		assert data.TryPublish() == PacketDataResult.Success
		assert responder.TryRead(0, value) == PacketDataResult.Success
		assert value == 0x82
		assert this.PrepareRequest(request, mac, ip, 41) == PacketDataResult.Invalid
		assert responder.GetAvailableLength() == 0
		assert responder.TryRead(0, value) == PacketDataResult.NotReady
		assert this.PrepareRequest(request, mac, ip, 42) == PacketDataResult.Success
		assert responder.TryRead(0, value) == PacketDataResult.Success
		assert value == 0x01
		request[13] = 0x00
		assert this.PrepareRequest(request, mac, ip, 42) == PacketDataResult.Invalid
		assert !responder.IsReady()
		responder.Invalidate()
	}

	/**
	 * Loads the explicit test prefix into the component-based response API.
	 */
	fn PrepareRequest(bytes: byte[64], mac: byte[6], ip: byte[4], length: int) PacketDataResult
	{
		responder.Invalidate()

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

		for (var i = 0; i < length; i++) {
			assert data.TryWrite(i, bytes[i]) == PacketDataResult.Success
		}

		assert data.TryPublish() == PacketDataResult.Success
		return responder.TryPrepare(mac, ip)
	}
}