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/arp/ArpResponder.lvt
namespace Livt.Net
/**
* Prepares an ARP reply from a bound frame provider; response addresses are snapshots.
*/
component ArpResponder<S: IPacketData> : IPacketData
{
// Borrowed shared parsers; consumers must serialize their use.
ethernet: EthernetFrameParser<S>
parser: ArpPacketParser<EthernetFrameParser<S>>
// Owned reply snapshot and its Ethernet envelope.
reply: ArpReply
frame: ArpReplyFrame
/**
* Borrows the shared Ethernet parser and owns ARP parsing and reply composition.
* The supplied parser must use the same source and clock/reset domain as its owner.
*/
new(ethernet: EthernetFrameParser<S>)
{
this.ethernet = ethernet
parser = new ArpPacketParser<EthernetFrameParser<S>>(ethernet)
reply = new ArpReply()
frame = new ArpReplyFrame(reply)
}
/**
* Invalidates response and input views after outstanding response borrows finish.
*/
public fn Invalidate()
{
frame.Invalidate()
reply.Invalidate()
parser.Invalidate()
ethernet.Invalidate()
}
/**
* Replaces the prior response even on rejection; requires Ethernet/IPv4 ARP for the local IP.
*/
public fn TryPrepare(localMac: byte[6], localIp: byte[4]) PacketDataResult
{
this.Invalidate()
ethernet.TryParse()
return this.TryPrepareParsed(localMac, localIp)
}
/**
* Consumes the shared validated Ethernet view without rereading its header.
* Requires exclusive use of the parser; closes request views on completion.
*/
public fn TryPrepareParsed(localMac: byte[6], localIp: byte[4]) PacketDataResult
{
frame.Invalidate()
reply.Invalidate()
parser.Invalidate()
if (!ethernet.IsReady() || ethernet.GetEtherType() != IEthernetPayload.ETHER_TYPE_ARP) {
return PacketDataResult.Invalid
}
if (parser.TryParse() != PacketParseResult.Success) {
return PacketDataResult.Invalid
}
if (parser.GetOperation() != 1) {
return PacketDataResult.Invalid
}
var destination = parser.GetTargetIpv4()
if (destination[0] != localIp[0] || destination[1] != localIp[1] || destination[2] != localIp[2] || destination[3] != localIp[3]) {
return PacketDataResult.Invalid
}
var peerMac = parser.GetSenderMac()
var peerIp = parser.GetSenderIpv4()
parser.Invalidate()
ethernet.Invalidate()
var result = reply.TryPrepare(localMac, localIp, peerMac, peerIp)
if (result != PacketDataResult.Success) {
return result
}
return frame.TryPrepare(localMac, peerMac)
}
/**
* Reports prepared reply availability.
*/
override fn IsReady() bool
{
return frame.IsReady()
}
/**
* Returns the complete padded reply length.
*/
override fn GetAvailableLength() int
{
return frame.GetAvailableLength()
}
/**
* Reads a prepared reply byte; request storage is no longer needed.
*/
override fn TryRead(index: int, value: out byte) PacketDataResult
{
return frame.TryRead(index, value)
}
}