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

namespace Livt.Net.Tests

using Livt.Net

/**
 * Exercises provider-relative parsing, independent expected values and reuse.
 */
@Test
component Ipv4PacketParserTest
{
	data: ArrayPacketData<128>
	region: PacketRegion<ArrayPacketData<128>>
	parser: Ipv4PacketParser<PacketRegion<ArrayPacketData<128>>>

	/**
	 * Wires packet storage and a deliberately offset protocol region.
	 */
	new()
	{
		data = new ArrayPacketData<128>()
		region = new PacketRegion<ArrayPacketData<128>>(data)
		parser = new Ipv4PacketParser<PacketRegion<ArrayPacketData<128>>>(region)
	}

	/**
	 * Replaces a fixture with correct descendant-first invalidation.
	 */
	fn Load(bytes: byte[128], length: int)
	{
		parser.Invalidate()
		region.TryClose()

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

		for (var i = 0; i < 7; i++) {
			assert data.TryWrite(i, 0xA5) == PacketDataResult.Success
		}

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

		assert data.TryPublish() == PacketDataResult.Success
		assert region.TryOpen(7, length) == PacketDataResult.Success
	}

	/**
	 * DecodesUnsignedFieldsAndBoundsDeclaredPayload.
	 */
	@Test
	fn DecodesUnsignedFieldsAndBoundsDeclaredPayload()
	{
		var bytes: byte[128]
		bytes[0] = 0x45
		bytes[3] = 0x28
		bytes[6] = 0x40
		bytes[9] = 0x06
		bytes[4] = 0xFE
		bytes[5] = 0xDC
		bytes[12] = 0xC0
		bytes[16] = 0x80
		bytes[20] = 0xAB
		bytes[40] = 0xEE
		this.Load(bytes, 50)
		assert parser.TryParse() == PacketParseResult.Success
		assert parser.GetTotalLength() == 40
		assert parser.GetIdentification() == 65244
		assert parser.GetProtocol() == 6
		assert parser.GetDeclaredPayloadLength() == 20
		assert parser.GetAvailableLength() == 20
		var source = parser.GetSourceIpv4()
		var destination = parser.GetDestinationIpv4()
		assert source[0] == 0xC0
		assert destination[0] == 0x80
		var value: byte = 0x00
		assert parser.TryRead(0, value) == PacketDataResult.Success
		assert value == 0xAB
		assert parser.TryRead(20, value) == PacketDataResult.Invalid
	}

	/**
	 * DistinguishesPartialCaptureAndInvalidHeader.
	 */
	@Test
	fn DistinguishesPartialCaptureAndInvalidHeader()
	{
		var bytes: byte[128]
		bytes[0] = 0x45
		bytes[3] = 0x28
		bytes[6] = 0x40
		bytes[9] = 0x06
		bytes[2] = 0x80
		bytes[3] = 0x01
		this.Load(bytes, 23)
		assert parser.TryParse() == PacketParseResult.HeaderOnly
		assert parser.GetTotalLength() == 32769
		assert parser.GetAvailableLength() == 3
		this.Load(bytes, 19)
		assert parser.TryParse() == PacketParseResult.Truncated
		assert parser.GetTotalLength() == 0
		bytes[2] = 0x00
		bytes[3] = 0x13
		this.Load(bytes, 20)
		assert parser.TryParse() == PacketParseResult.Invalid
		assert !parser.IsReady()
	}

	/**
	 * RejectsOptionsFragmentsAndWrongVersion.
	 */
	@Test
	fn RejectsOptionsFragmentsAndWrongVersion()
	{
		var bytes: byte[128]
		bytes[0] = 0x45
		bytes[3] = 0x28
		bytes[6] = 0x40
		bytes[9] = 0x06
		bytes[0] = 0x46
		this.Load(bytes, 40)
		assert parser.TryParse() == PacketParseResult.Unsupported
		bytes[0] = 0x45
		bytes[6] = 0x20
		this.Load(bytes, 40)
		assert parser.TryParse() == PacketParseResult.Unsupported
		bytes[6] = 0x40
		bytes[0] = 0x65
		this.Load(bytes, 40)
		assert parser.TryParse() == PacketParseResult.Unsupported
		bytes[0] = 0x44
		this.Load(bytes, 40)
		assert parser.TryParse() == PacketParseResult.Invalid
	}

	/**
	 * ChecksHeaderChecksumSeparatelyAndClearsOnReuse.
	 */
	@Test
	fn ChecksHeaderChecksumSeparatelyAndClearsOnReuse()
	{
		var bytes: byte[128]
		bytes[0] = 0x45
		bytes[3] = 0x14
		bytes[8] = 0x40
		bytes[9] = 0x01
		bytes[10] = 0x7A
		bytes[11] = 0xEA
		this.Load(bytes, 20)
		assert parser.TryParse() == PacketParseResult.Success
		assert parser.IsHeaderChecksumValid()
		bytes[11] = 0xEB
		this.Load(bytes, 20)
		assert parser.TryParse() == PacketParseResult.Success
		assert !parser.IsHeaderChecksumValid()
		parser.Invalidate()
		region.TryClose()
		data.TryRelease()
		assert parser.GetStatus() == PacketParseResult.NotReady
		assert parser.GetTotalLength() == 0
		var value: byte = 0xFF
		assert parser.TryRead(0, value) == PacketDataResult.NotReady
		assert value == 0x00
	}
}