all repos

scratch @ 2b64f4e6f2d35ae68bf39cec616a782153335bc0

⭐ me doing recreational ~~drugs~~ programming

scratch/dns-server/packet.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
dns: ch5, 1 month ago
1
package main
2
3
import (
4
	"bytes"
5
	"net"
6
	"strings"
7
)
8
9
type Packet struct {
10
	Header      Header
11
	Questions   []Question
12
	Answers     []Record
13
	Authorities []Record
14
	Resources   []Record
15
}
16
17
func ParsePacket(packet []byte) (Packet, error) {
18
	r := bytes.NewReader(packet)
19
20
	var err error
21
	var p Packet
22
23
	p.Header, err = ReadHeader(r)
24
	if err != nil {
25
		return Packet{}, err
26
	}
27
28
	for i := 0; i < int(p.Header.Questions); i++ {
29
		q, err := ReadQuestion(r, packet)
30
		if err != nil {
31
			return Packet{}, err
32
		}
33
		p.Questions = append(p.Questions, q)
34
	}
35
36
	for i := 0; i < int(p.Header.Answers); i++ {
37
		a, err := ReadRecord(r, packet)
38
		if err != nil {
39
			return Packet{}, err
40
		}
41
		p.Answers = append(p.Answers, a)
42
	}
43
44
	for i := 0; i < int(p.Header.AuthoritativeEntries); i++ {
45
		ae, err := ReadRecord(r, packet)
46
		if err != nil {
47
			return Packet{}, err
48
		}
49
		p.Authorities = append(p.Authorities, ae)
50
	}
51
52
	for i := 0; i < int(p.Header.ResourceEntries); i++ {
53
		re, err := ReadRecord(r, packet)
54
		if err != nil {
55
			return Packet{}, err
56
		}
57
		p.Resources = append(p.Resources, re)
58
	}
59
60
	return p, nil
61
}
62
63
func (p *Packet) Write(b *bytes.Buffer) error {
64
	p.Header.Questions = uint16(len(p.Questions))
65
	p.Header.Answers = uint16(len(p.Answers))
66
	p.Header.AuthoritativeEntries = uint16(len(p.Authorities))
67
	p.Header.ResourceEntries = uint16(len(p.Resources))
68
	_ = p.Header.Write(b)
69
70
	for i := range p.Questions {
71
		_ = p.Questions[i].Write(b)
72
	}
73
74
	for i := range p.Answers {
75
		_, _ = p.Answers[i].Write(b)
76
	}
77
78
	for i := range p.Authorities {
79
		_, _ = p.Authorities[i].Write(b)
80
	}
81
82
	for i := range p.Resources {
83
		_, _ = p.Resources[i].Write(b)
84
	}
85
86
	return nil
87
}
88
89
func (p Packet) GetRandomA() (net.IP, bool) {
90
	for _, r := range p.Answers {
91
		if r.Type == AType {
92
			return net.ParseIP(r.Data), true
93
		}
94
	}
95
	return nil, false
96
}
97
98
func (p Packet) GetResolvedNS(qname string) (net.IP, bool) {
99
	for _, ns := range p.getNS(qname) {
100
		host := ns[1]
101
		for _, r := range p.Resources {
102
			if r.Type == AType && r.Name == host {
103
				return net.ParseIP(r.Data), true
104
			}
105
		}
106
	}
107
	return nil, false
108
}
109
110
func (p Packet) GetUnresolvedNS(qname string) (string, bool) {
111
	ns := p.getNS(qname)
112
	if len(ns) == 0 {
113
		return "", false
114
	}
115
	return ns[0][1], true
116
}
117
118
func (p Packet) getNS(qname string) [][2]string {
119
	var res [][2]string
120
	for _, r := range p.Authorities {
121
		if r.Type == NSType && strings.HasPrefix(qname, r.Name) {
122
			res = append(res, [2]string{r.Name, r.Data})
123
		}
124
	}
125
	return res
126
}