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/TcpConnectionRecognizer.lvt
namespace Livt.Net
/**
* Recognizes endpoint policy over one parsed Ethernet/IPv4/TCP graph.
*/
component TcpConnectionRecognizer<S: IPacketData> : IPacketData
{
// Borrowed shared parser pair and owned TCP descendant.
ethernet: EthernetFrameParser<S>
ipv4: Ipv4PacketParser<EthernetFrameParser<S>>
tcp: TcpHeaderParser<Ipv4PacketParser<EthernetFrameParser<S>>>
// Validation state for the current recognition lifetime.
status: PacketParseResult
/**
* Borrows the shared Ethernet/IPv4 pair; creates only the TCP descendant.
* One serialized owner must invalidate this descendant before reusing either parser.
*/
new(ethernet: EthernetFrameParser<S>, ipv4: Ipv4PacketParser<EthernetFrameParser<S>>)
{
this.ethernet = ethernet
this.ipv4 = ipv4
tcp = new TcpHeaderParser<Ipv4PacketParser<EthernetFrameParser<S>>>(ipv4)
}
/**
* Closes descendants before ancestors; call before source release or reuse.
*/
public fn Invalidate()
{
tcp.Invalidate()
ipv4.Invalidate()
ethernet.Invalidate()
status = PacketParseResult.NotReady
}
/**
* Parses once; HeaderOnly preserves incomplete IP capture explicitly. No checksum enforcement.
*/
public fn TryParse() PacketParseResult
{
this.Invalidate()
status = ethernet.TryParse()
if (!ethernet.IsReady()) {
return status
}
if (ethernet.GetEtherType() != IEthernetPayload.ETHER_TYPE_IPV4) {
status = PacketParseResult.Unsupported
return status
}
status = ipv4.TryParse()
if (!ipv4.IsReady()) {
return status
}
if (ipv4.GetProtocol() != IIpv4Payload.PROTOCOL_TCP) {
status = PacketParseResult.Unsupported
return status
}
var tcpStatus = tcp.TryParse()
if (tcpStatus != PacketParseResult.Success) {
status = tcpStatus
}
return status
}
/**
* Returns structural status without implying checksum or wire-length validation.
*/
public fn GetStatus() PacketParseResult
{
if ((status == PacketParseResult.Success || status == PacketParseResult.HeaderOnly) && !tcp.IsReady()) {
return PacketParseResult.NotReady
}
return status
}
/**
* Applies endpoint policy separately from structural parsing.
*/
public fn IsForEndpoint(localIp: byte[4], localPort: int) bool
{
if (!this.IsReady()) {
return false
}
var destination = ipv4.GetDestinationIpv4()
if (destination[0] != localIp[0] || destination[1] != localIp[1] || destination[2] != localIp[2] || destination[3] != localIp[3]) {
return false
}
return tcp.GetDestinationPort() == localPort
}
/**
* Recognizes the supported flags and endpoint; SYN options are accepted but not interpreted.
*/
public fn IsSynRequest(localIp: byte[4], localPort: int) bool
{
return this.IsForEndpoint(localIp, localPort) && tcp.GetFlags() == 2
}
/**
* Recognizes the supported flags and endpoint; SYN options are accepted but not interpreted.
*/
public fn IsAckOnlyPacket(localIp: byte[4], localPort: int) bool
{
return this.IsForEndpoint(localIp, localPort) && tcp.GetFlags() == 16 && tcp.GetHeaderLength() == 20
}
/**
* Recognizes the supported flags and endpoint; SYN options are accepted but not interpreted.
*/
public fn IsPshAckPacket(localIp: byte[4], localPort: int) bool
{
return this.IsForEndpoint(localIp, localPort) && tcp.GetFlags() == 24 && tcp.GetHeaderLength() == 20
}
/** Returns the peer MAC only while the complete protocol graph is usable. */
public fn GetSourceMac() byte[6]
{
var empty: byte[6] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
if (!this.IsReady()) {
return empty
}
return this.ethernet.GetSourceMac()
}
/**
* Returns cached metadata only while the composed parse is usable.
*/
public fn GetSourceIpv4() byte[4]
{
var empty: byte[4] = [0x00, 0x00, 0x00, 0x00]
if (!this.IsReady()) {
return empty
}
return ipv4.GetSourceIpv4()
}
/**
* Returns cached metadata only while the composed parse is usable.
*/
public fn GetSourcePort() int
{
if (!this.IsReady()) {
return 0
}
return tcp.GetSourcePort()
}
/**
* Returns cached metadata only while the composed parse is usable.
*/
public fn GetSequenceNumber() uint
{
if (!this.IsReady()) {
return 0
}
return tcp.GetSequenceNumber()
}
/**
* Returns cached metadata only while the composed parse is usable.
*/
public fn GetDeclaredPayloadLength() int
{
if (!this.IsReady()) {
return 0
}
return ipv4.GetDeclaredPayloadLength() - tcp.GetHeaderLength()
}
/**
* Reports supported headers, allowing a captured prefix of the payload.
*/
override fn IsReady() bool
{
return (status == PacketParseResult.Success || status == PacketParseResult.HeaderOnly) && tcp.IsReady()
}
/**
* Returns captured TCP payload size, excluding enclosing padding.
*/
override fn GetAvailableLength() int
{
if (!this.IsReady()) {
return 0
}
return tcp.GetAvailableLength()
}
/**
* Reads the bounded TCP payload. The source remains borrowed until invalidation.
*/
override fn TryRead(index: int, value: out byte) PacketDataResult
{
value = 0x00
if (!this.IsReady()) {
return PacketDataResult.NotReady
}
var readValue: byte = 0x00
var result = tcp.TryRead(index, readValue)
value = readValue
return result
}
}