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/services/FrameClassification.lvt

namespace Livt.Net

/**
 * Decoded protocol identity, distinct from endpoint acceptance or response selection.
 */
enum NetworkProtocol
{
	Unknown
	Arp
	Ipv4Other
	Icmp
	Tcp
	Udp
}

/**
 * Snapshots reusable Ethernet/IPv4 diagnostics and closes input views on return.
 * This does not assert checksum validity or manufacture wire-length knowledge.
 */
component FrameClassification<S: IPacketData>
{
	// Borrowed parser pair shared with serialized protocol services.
	ethernet: EthernetFrameParser<S>
	ipv4: Ipv4PacketParser<EthernetFrameParser<S>>

	// Last supported protocol and local destination match.
	protocol: NetworkProtocol
	local: bool

	/**
	 * Borrows a shared Ethernet/IPv4 pair without reading the fixed request source.
	 * Inspect requires exclusive use; close other descendants before calling it.
	 */
	new(ethernet: EthernetFrameParser<S>, ipv4: Ipv4PacketParser<EthernetFrameParser<S>>)
	{
		this.ethernet = ethernet
		this.ipv4 = ipv4
	}

	/**
	 * Clears prior diagnostics and all request views before source reuse.
	 */
	public fn Clear()
	{
		this.ipv4.Invalidate()
		this.ethernet.Invalidate()
		this.protocol = NetworkProtocol.Unknown
		this.local = false
	}

	/**
	 * Records supported metadata, including captured IPv4 prefixes, then closes views.
	 */
	public fn Inspect(localIp: byte[4])
	{
		this.Clear()
		this.ethernet.TryParse()

		if (!this.ethernet.IsReady()) {
			this.ethernet.Invalidate()
			return
		}

		var etherType = this.ethernet.GetEtherType()

		if (etherType == IEthernetPayload.ETHER_TYPE_ARP) {
			this.protocol = NetworkProtocol.Arp
		}

		if (etherType == IEthernetPayload.ETHER_TYPE_IPV4) {
			this.ipv4.TryParse()

			if (this.ipv4.IsReady()) {
				this.protocol = NetworkProtocol.Ipv4Other
				var number = this.ipv4.GetProtocol()

				if (number == IIpv4Payload.PROTOCOL_ICMP) {
					this.protocol = NetworkProtocol.Icmp
				}
				elif (number == IIpv4Payload.PROTOCOL_TCP) {
					this.protocol = NetworkProtocol.Tcp
				}
				elif (number == IIpv4Payload.PROTOCOL_UDP) {
					this.protocol = NetworkProtocol.Udp
				}

				var destination = this.ipv4.GetDestinationIpv4()
				this.local = destination[0] == localIp[0] && destination[1] == localIp[1]
					&& destination[2] == localIp[2] && destination[3] == localIp[3]
			}
		}

		this.ipv4.Invalidate()
		this.ethernet.Invalidate()
	}

	/**
	 * Returns the last decoded protocol; Unknown includes unsupported/truncated headers.
	 */
	public fn GetProtocol() NetworkProtocol
	{
		return this.protocol
	}

	/**
	 * Reports supported IPv4 metadata addressed to the configured local IP.
	 */
	public fn IsForLocalIp() bool
	{
		return this.local
	}
}