mirror of
https://github.com/soypat/lneto.git
synced 2026-09-10 08:39:30 +00:00
Add mdns package and Client implementation (#55)
* add mdns * define mdns.Client * fix some mdns stuff * refine dns package for use with mdns * remove Querier and Responder and replace with Client * add record setting methods on dns.record to reuse record buffer * protect against unbounded client answer growth * round off sharp mdns edges; reduce allocs * add mutlicast to stacks; add xnet tests for mdns * fix documentation on acceptmulticast field * mdns working
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/soypat/lneto/ipv4"
|
||||
"github.com/soypat/lneto/ipv4/icmpv4"
|
||||
"github.com/soypat/lneto/ipv6"
|
||||
"github.com/soypat/lneto/mdns"
|
||||
"github.com/soypat/lneto/ntp"
|
||||
"github.com/soypat/lneto/tcp"
|
||||
"github.com/soypat/lneto/udp"
|
||||
@@ -359,7 +360,7 @@ func (pc *PacketBreakdown) CaptureUDP(dst []Frame, pkt []byte, bitOffset int) ([
|
||||
srcport := ufrm.SourcePort()
|
||||
if dhcpv4.PayloadIsDHCPv4(payload) {
|
||||
dst, err = pc.CaptureDHCPv4(dst, pkt, end)
|
||||
} else if dstport == dns.ServerPort || srcport == dns.ServerPort {
|
||||
} else if dstport == dns.ServerPort || srcport == dns.ServerPort || dstport == mdns.Port || srcport == mdns.Port {
|
||||
dst, err = pc.CaptureDNS(dst, pkt, end)
|
||||
} else if dstport == ntp.ServerPort || srcport == ntp.ServerPort {
|
||||
dst, err = pc.CaptureNTP(dst, pkt, end)
|
||||
@@ -437,7 +438,7 @@ func (pc *PacketBreakdown) CaptureDNS(dst []Frame, pkt []byte, bitOffset int) ([
|
||||
return dst, errNotByteAligned
|
||||
}
|
||||
dnsData := pkt[bitOffset/8:]
|
||||
pc.dmsg.LimitResourceDecoding(20, 20, 20, 20)
|
||||
pc.dmsg.LimitResourceDecoding(4, 4, 4, 4)
|
||||
off, incomplete, err := pc.dmsg.Decode(dnsData)
|
||||
if err != nil && !incomplete {
|
||||
return dst, err
|
||||
@@ -1265,6 +1266,43 @@ var baseDHCPv4Fields = [...]FrameField{
|
||||
},
|
||||
}
|
||||
|
||||
var baseDNSFields = [...]FrameField{
|
||||
{
|
||||
Class: FieldClassID,
|
||||
FrameBitOffset: 0,
|
||||
BitLength: 2 * octet,
|
||||
},
|
||||
{
|
||||
Class: FieldClassFlags,
|
||||
FrameBitOffset: 2 * octet,
|
||||
BitLength: 2 * octet,
|
||||
},
|
||||
{
|
||||
Name: "Questions",
|
||||
Class: FieldClassSize,
|
||||
FrameBitOffset: 4 * octet,
|
||||
BitLength: 2 * octet,
|
||||
},
|
||||
{
|
||||
Name: "Answers",
|
||||
Class: FieldClassSize,
|
||||
FrameBitOffset: 6 * octet,
|
||||
BitLength: 2 * octet,
|
||||
},
|
||||
{
|
||||
Name: "Authorities",
|
||||
Class: FieldClassSize,
|
||||
FrameBitOffset: 8 * octet,
|
||||
BitLength: 2 * octet,
|
||||
},
|
||||
{
|
||||
Name: "Additionals",
|
||||
Class: FieldClassSize,
|
||||
FrameBitOffset: 10 * octet,
|
||||
BitLength: 2 * octet,
|
||||
},
|
||||
}
|
||||
|
||||
var baseNTPFields = [...]FrameField{
|
||||
{
|
||||
Name: "Mode",
|
||||
|
||||
+19
-11
@@ -33,11 +33,12 @@ type StackEthernetConfig struct {
|
||||
}
|
||||
|
||||
type StackEthernet struct {
|
||||
connID uint64
|
||||
handlers handlers
|
||||
mac [6]byte
|
||||
gwmac [6]byte
|
||||
mtu uint16
|
||||
connID uint64
|
||||
handlers handlers
|
||||
mac [6]byte
|
||||
gwmac [6]byte
|
||||
mtu uint16
|
||||
acceptMulticast bool
|
||||
// crcupdate set when crc32 has been configured to be appended.
|
||||
crcupdate func(crc uint32, p []byte) uint32
|
||||
}
|
||||
@@ -50,6 +51,10 @@ func (ls *StackEthernet) Gateway6() (gw [6]byte) {
|
||||
return ls.gwmac
|
||||
}
|
||||
|
||||
func (ls *StackEthernet) SetAcceptMulticast(accept bool) {
|
||||
ls.acceptMulticast = accept
|
||||
}
|
||||
|
||||
func (ls *StackEthernet) SetHardwareAddr6(mac [6]byte) {
|
||||
ls.mac = mac
|
||||
}
|
||||
@@ -83,11 +88,12 @@ func (ls *StackEthernet) Configure(cfg StackEthernetConfig) error {
|
||||
}
|
||||
ls.handlers.reset("StackEthernet", cfg.MaxNodes)
|
||||
*ls = StackEthernet{
|
||||
connID: ls.connID + 1,
|
||||
handlers: ls.handlers,
|
||||
mac: cfg.MAC,
|
||||
gwmac: cfg.Gateway,
|
||||
mtu: uint16(cfg.MTU),
|
||||
connID: ls.connID + 1,
|
||||
handlers: ls.handlers,
|
||||
mac: cfg.MAC,
|
||||
gwmac: cfg.Gateway,
|
||||
mtu: uint16(cfg.MTU),
|
||||
acceptMulticast: ls.acceptMulticast,
|
||||
}
|
||||
if cfg.AppendCRC32 {
|
||||
ls.crcupdate = cfg.CRC32Update
|
||||
@@ -121,7 +127,9 @@ func (ls *StackEthernet) Demux(carrierData []byte, frameOffset int) (err error)
|
||||
dstaddr := efrm.DestinationHardwareAddr()
|
||||
var vld lneto.Validator
|
||||
if !efrm.IsBroadcast() && ls.mac != *dstaddr {
|
||||
goto DROP
|
||||
if !ls.acceptMulticast || dstaddr[0]&1 == 0 {
|
||||
goto DROP
|
||||
}
|
||||
}
|
||||
efrm.ValidateSize(&vld)
|
||||
if vld.HasError() {
|
||||
|
||||
+19
-11
@@ -16,11 +16,12 @@ import (
|
||||
var _ StackNode = (*StackIP)(nil)
|
||||
|
||||
type StackIP struct {
|
||||
connID uint64
|
||||
ipID uint16
|
||||
ip [4]byte
|
||||
validator lneto.Validator
|
||||
handlers handlers
|
||||
connID uint64
|
||||
ipID uint16
|
||||
ip [4]byte
|
||||
acceptMulticast bool
|
||||
validator lneto.Validator
|
||||
handlers handlers
|
||||
}
|
||||
|
||||
func (sb *StackIP) Reset(addr netip.Addr, maxNodes int) error {
|
||||
@@ -33,10 +34,11 @@ func (sb *StackIP) Reset(addr netip.Addr, maxNodes int) error {
|
||||
}
|
||||
sb.handlers.reset("StackIP", maxNodes)
|
||||
*sb = StackIP{
|
||||
connID: sb.connID + 1,
|
||||
validator: sb.validator,
|
||||
handlers: sb.handlers,
|
||||
ip: sb.ip,
|
||||
connID: sb.connID + 1,
|
||||
validator: sb.validator,
|
||||
handlers: sb.handlers,
|
||||
ip: sb.ip,
|
||||
acceptMulticast: sb.acceptMulticast,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -65,6 +67,10 @@ func (sb *StackIP) Addr() netip.Addr {
|
||||
return netip.AddrFrom4(sb.ip)
|
||||
}
|
||||
|
||||
func (sb *StackIP) SetAcceptMulticast(accept bool) {
|
||||
sb.acceptMulticast = accept
|
||||
}
|
||||
|
||||
func (sb *StackIP) SetLogger(logger *slog.Logger) {
|
||||
sb.handlers.log = logger
|
||||
}
|
||||
@@ -79,8 +85,10 @@ func (sb *StackIP) Demux(carrierData []byte, offset int) error {
|
||||
}
|
||||
dst := ifrm.DestinationAddr()
|
||||
if sb.ip != ([4]byte{}) && *dst != sb.ip {
|
||||
sb.handlers.debug("ip:not-for-us")
|
||||
return lneto.ErrPacketDrop // Not meant for us.
|
||||
if !sb.acceptMulticast || dst[0]&0xF0 != 0xE0 {
|
||||
sb.handlers.debug("ip:not-for-us")
|
||||
return lneto.ErrPacketDrop // Not meant for us.
|
||||
}
|
||||
}
|
||||
|
||||
sb.validator.ResetErr()
|
||||
|
||||
Reference in New Issue
Block a user