DNS resolution working butter smooth

This commit is contained in:
soypat
2025-07-12 12:54:34 -03:00
parent 68c4d1ea71
commit 698610242e
5 changed files with 66 additions and 18 deletions
+6 -6
View File
@@ -65,12 +65,12 @@ func (c *Client) Encapsulate(carrierData []byte, frameOffset int) (int, error) {
} }
c.state = dnsAwaitResponse c.state = dnsAwaitResponse
// Unset don't frag since DNS requests go through LOTS of nodes. // Unset don't frag since DNS requests go through LOTS of nodes.
if frameOffset >= 28 { // if frameOffset >= 28 {
version := carrierData[0] >> 4 // version := carrierData[0] >> 4
if version == 4 { // if version == 4 {
carrierData[6], carrierData[7] = 0, 0 // unset IP Flags. // carrierData[6], carrierData[7] = 0, 0 // unset IP Flags.
} // }
} // }
return len(data), nil return len(data), nil
} }
+2 -2
View File
@@ -626,10 +626,10 @@ func (dst *Message) CopyFrom(m Message) {
for i := range dst.Answers { for i := range dst.Answers {
dst.Answers[i].CopyFrom(m.Answers[i]) dst.Answers[i].CopyFrom(m.Answers[i])
} }
for i := range dst.Answers { for i := range dst.Authorities {
dst.Authorities[i].CopyFrom(m.Authorities[i]) dst.Authorities[i].CopyFrom(m.Authorities[i])
} }
for i := range dst.Answers { for i := range dst.Additionals {
dst.Additionals[i].CopyFrom(m.Additionals[i]) dst.Additionals[i].CopyFrom(m.Additionals[i])
} }
} }
+15
View File
@@ -221,3 +221,18 @@ func (m *Message) String() string {
} }
return s return s
} }
func TestDecodeMessage(t *testing.T) {
var data = []byte{
0x84, 0x05, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x77, 0x68, 0x69,
0x74, 0x74, 0x69, 0x6c, 0x65, 0x61, 0x6b, 0x73, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1e, 0xaf, 0x00, 0x04, 0xc6, 0x31, 0x17,
0x91, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
var msg Message
msg.LimitResourceDecoding(5, 5, 5, 5)
off, incomplete, err := msg.Decode(data)
if incomplete || err != nil {
t.Fatal(incomplete, err, off)
}
}
+8 -6
View File
@@ -137,10 +137,12 @@ func run() (err error) {
} }
case stateDNS: case stateDNS:
addrs, err := stack.ResultLookupIP() addrs, done, err := stack.ResultLookupIP()
if err == nil { if err == nil {
fmt.Println(flagHostToResolve, "resolved to", addrs) fmt.Println(flagHostToResolve, "resolved to", addrs)
return nil return nil
} else if done {
return err
} }
} }
@@ -197,7 +199,7 @@ func (s *Stack) Demux(b []byte, _ int) (err error) {
s.aux, err = s.shark.CaptureEthernet(s.aux[:0], b, 0) s.aux, err = s.shark.CaptureEthernet(s.aux[:0], b, 0)
topFrame := s.aux[len(s.aux)-1] topFrame := s.aux[len(s.aux)-1]
isOK := topFrame.Protocol == "DHCPv4" || // Allow DHCP responses. isOK := topFrame.Protocol == "DHCPv4" || // Allow DHCP responses.
(topFrame.Protocol == lneto.IPProtoUDP && getField(topFrame, b, pcap.FieldClassSrc) == 53) || // Allow DNS responses. topFrame.Protocol == "DNS" ||
topFrame.Protocol == ethernet.TypeARP // Allow ARP responses. topFrame.Protocol == ethernet.TypeARP // Allow ARP responses.
if !isOK { if !isOK {
return nil return nil
@@ -308,12 +310,12 @@ func (s *Stack) StartLookupIP(host string) error {
return nil return nil
} }
func (s *Stack) ResultLookupIP() ([]netip.Addr, error) { func (s *Stack) ResultLookupIP() ([]netip.Addr, bool, error) {
done, err := s.dns.MessageCopyTo(&s.lookup) done, err := s.dns.MessageCopyTo(&s.lookup)
if err != nil { if err != nil {
return nil, err return nil, done, err
} else if !done { } else if !done {
return nil, errors.New("DNS not done") return nil, done, errors.New("DNS not done")
} }
var addrs []netip.Addr var addrs []netip.Addr
ans := s.lookup.Answers ans := s.lookup.Answers
@@ -325,7 +327,7 @@ func (s *Stack) ResultLookupIP() ([]netip.Addr, error) {
addrs = append(addrs, netip.AddrFrom16([16]byte(data))) addrs = append(addrs, netip.AddrFrom16([16]byte(data)))
} }
} }
return addrs, nil return addrs, done, nil
} }
func (s *Stack) BeginDHCPRequest(request [4]byte) error { func (s *Stack) BeginDHCPRequest(request [4]byte) error {
+35 -4
View File
@@ -10,6 +10,7 @@ import (
"github.com/soypat/lneto" "github.com/soypat/lneto"
"github.com/soypat/lneto/arp" "github.com/soypat/lneto/arp"
"github.com/soypat/lneto/dhcpv4" "github.com/soypat/lneto/dhcpv4"
"github.com/soypat/lneto/dns"
"github.com/soypat/lneto/ethernet" "github.com/soypat/lneto/ethernet"
"github.com/soypat/lneto/http/httpraw" "github.com/soypat/lneto/http/httpraw"
"github.com/soypat/lneto/ipv4" "github.com/soypat/lneto/ipv4"
@@ -21,8 +22,9 @@ import (
const unknownPayloadProto = "payload?" const unknownPayloadProto = "payload?"
type PacketBreakdown struct { type PacketBreakdown struct {
hdr httpraw.Header hdr httpraw.Header
vld lneto.Validator dmsg dns.Message
vld lneto.Validator
} }
func (pc *PacketBreakdown) CaptureEthernet(dst []Frame, pkt []byte, bitOffset int) ([]Frame, error) { func (pc *PacketBreakdown) CaptureEthernet(dst []Frame, pkt []byte, bitOffset int) ([]Frame, error) {
@@ -323,13 +325,42 @@ func (pc *PacketBreakdown) CaptureUDP(dst []Frame, pkt []byte, bitOffset int) ([
end := bitOffset + 8*octet end := bitOffset + 8*octet
payload := ufrm.Payload() payload := ufrm.Payload()
if dhcpv4.PayloadIsDHCPv4(payload) { if dhcpv4.PayloadIsDHCPv4(payload) {
return pc.CaptureDHCPv4(dst, pkt, end) dst, err = pc.CaptureDHCPv4(dst, pkt, end)
} else { } else if ufrm.DestinationPort() == 53 || ufrm.SourcePort() == 53 {
dst, err = pc.CaptureDNS(dst, pkt, end)
}
if err != nil {
dst = append(dst, remainingFrameInfo(unknownPayloadProto, FieldClassPayload, end, octet*len(pkt))) dst = append(dst, remainingFrameInfo(unknownPayloadProto, FieldClassPayload, end, octet*len(pkt)))
} }
return dst, nil return dst, nil
} }
func (pc *PacketBreakdown) CaptureDNS(dst []Frame, pkt []byte, bitOffset int) ([]Frame, error) {
if bitOffset%8 != 0 {
return nil, errors.New("DNS must be parsed at byte boundary")
}
dnsData := pkt[bitOffset/8:]
pc.dmsg.LimitResourceDecoding(20, 20, 20, 20)
off, incomplete, err := pc.dmsg.Decode(dnsData)
if err != nil && !incomplete {
return dst, err
}
finfo := Frame{
Protocol: "DNS",
PacketBitOffset: bitOffset,
}
if incomplete {
finfo.Errors = append(finfo.Errors, errors.New("pcap: could not parse all DNS resources; add higher limit"))
}
finfo.Fields = append(finfo.Fields, FrameField{
Name: "Data",
FrameBitOffset: 0,
BitLength: int(off) * octet,
})
dst = append(dst, finfo)
return dst, nil
}
func (pc *PacketBreakdown) CaptureDHCPv4(dst []Frame, pkt []byte, bitOffset int) ([]Frame, error) { func (pc *PacketBreakdown) CaptureDHCPv4(dst []Frame, pkt []byte, bitOffset int) ([]Frame, error) {
if bitOffset%8 != 0 { if bitOffset%8 != 0 {
return nil, errors.New("DHCP must be parsed at byte boundary") return nil, errors.New("DHCP must be parsed at byte boundary")