91 lines
2.3 KiB
Go
91 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/miekg/dns"
|
|
"github.com/mr-karan/doggo/pkg/resolvers"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Lookup sends the DNS queries to the server.
|
|
// It prepares a list of `dns.Questions` and sends
|
|
// to all resolvers. It returns a list of []resolver.Response from
|
|
// each resolver
|
|
func (hub *Hub) Lookup() ([][]resolvers.Response, error) {
|
|
questions, err := hub.prepareQuestions()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
hub.Questions = questions
|
|
// for each type of resolver do a DNS lookup
|
|
responses := make([][]resolvers.Response, 0, len(hub.Questions))
|
|
for _, r := range hub.Resolver {
|
|
resp, err := r.Lookup(hub.Questions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
responses = append(responses, resp)
|
|
}
|
|
return responses, nil
|
|
}
|
|
|
|
// prepareQuestions takes a list of hostnames and some
|
|
// additional options and returns a list of all possible
|
|
// `dns.Questions`.
|
|
func (hub *Hub) prepareQuestions() ([]dns.Question, error) {
|
|
var (
|
|
questions []dns.Question
|
|
)
|
|
for _, name := range hub.QueryFlags.QNames {
|
|
var (
|
|
domains []string
|
|
)
|
|
// If `search` flag is specified then fetch the search list
|
|
// from `resolv.conf` and set the
|
|
if hub.QueryFlags.UseSearchList {
|
|
list, err := fetchDomainList(name, hub.QueryFlags.Ndots)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
domains = list
|
|
} else {
|
|
domains = []string{dns.Fqdn(name)}
|
|
}
|
|
for _, d := range domains {
|
|
hub.Logger.WithFields(logrus.Fields{
|
|
"domain": d,
|
|
"ndots": hub.QueryFlags.Ndots,
|
|
}).Debug("Attmepting to resolve")
|
|
question := dns.Question{
|
|
Name: d,
|
|
}
|
|
// iterate on a list of query types.
|
|
for _, q := range hub.QueryFlags.QTypes {
|
|
question.Qtype = dns.StringToType[strings.ToUpper(q)]
|
|
// iterate on a list of query classes.
|
|
for _, c := range hub.QueryFlags.QClasses {
|
|
question.Qclass = dns.StringToClass[strings.ToUpper(c)]
|
|
// append a new question for each possible pair.
|
|
questions = append(questions, question)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return questions, nil
|
|
}
|
|
|
|
func fetchDomainList(d string, ndots int) ([]string, error) {
|
|
if runtime.GOOS == "windows" {
|
|
// TODO: Add a method for reading system default nameserver in windows.
|
|
return []string{d}, nil
|
|
}
|
|
cfg, err := dns.ClientConfigFromFile(DefaultResolvConfPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cfg.Ndots = ndots
|
|
return cfg.NameList(d), nil
|
|
}
|