doggo/cmd/lookup.go

93 lines
2.3 KiB
Go
Raw Normal View History

2020-12-10 17:14:04 +01:00
package main
import (
"errors"
2020-12-17 12:27:44 +01:00
"runtime"
2020-12-10 17:14:04 +01:00
"strings"
"github.com/miekg/dns"
2020-12-13 08:15:45 +01:00
"github.com/mr-karan/doggo/pkg/resolvers"
"github.com/sirupsen/logrus"
2020-12-10 17:14:04 +01:00
)
2020-12-12 11:57:13 +01:00
// Lookup sends the DNS queries to the server.
2020-12-13 13:19:10 +01:00
func (hub *Hub) Lookup() error {
2020-12-17 12:27:44 +01:00
questions, err := hub.prepareQuestions()
2020-12-13 08:15:45 +01:00
if err != nil {
return err
}
2020-12-17 12:27:44 +01:00
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 err
}
responses = append(responses, resp)
}
if len(responses) == 0 {
return errors.New(`no DNS records found`)
2020-12-10 17:14:04 +01:00
}
2020-12-12 15:10:28 +01:00
hub.Output(responses)
2020-12-10 17:14:04 +01:00
return nil
}
2020-12-17 12:27:44 +01:00
// 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) {
2020-12-13 08:15:45 +01:00
var (
2020-12-17 12:27:44 +01:00
questions []dns.Question
2020-12-13 08:15:45 +01:00
)
2020-12-13 13:19:10 +01:00
for _, name := range hub.QueryFlags.QNames {
2020-12-13 08:15:45 +01:00
var (
domains []string
)
// If `search` flag is specified then fetch the search list
// from `resolv.conf` and set the
if hub.QueryFlags.UseSearchList {
2020-12-17 12:27:44 +01:00
list, err := fetchDomainList(name, hub.QueryFlags.Ndots)
2020-12-13 08:15:45 +01:00
if err != nil {
2020-12-17 12:27:44 +01:00
return nil, err
2020-12-13 08:15:45 +01:00
}
domains = list
} else {
domains = []string{dns.Fqdn(name)}
}
for _, d := range domains {
hub.Logger.WithFields(logrus.Fields{
"domain": d,
2020-12-17 12:27:44 +01:00
"ndots": hub.QueryFlags.Ndots,
2020-12-13 08:15:45 +01:00
}).Debug("Attmepting to resolve")
2020-12-17 12:27:44 +01:00
question := dns.Question{}
2020-12-13 08:15:45 +01:00
question.Name = d
// iterate on a list of query types.
2020-12-13 13:19:10 +01:00
for _, q := range hub.QueryFlags.QTypes {
2020-12-13 08:15:45 +01:00
question.Qtype = dns.StringToType[strings.ToUpper(q)]
// iterate on a list of query classes.
2020-12-13 13:19:10 +01:00
for _, c := range hub.QueryFlags.QClasses {
2020-12-13 08:15:45 +01:00
question.Qclass = dns.StringToClass[strings.ToUpper(c)]
// append a new question for each possible pair.
2020-12-17 12:27:44 +01:00
questions = append(questions, question)
2020-12-13 08:15:45 +01:00
}
2020-12-10 17:14:04 +01:00
}
}
}
2020-12-17 12:27:44 +01:00
return questions, nil
2020-12-13 08:15:45 +01:00
}
2020-12-17 12:27:44 +01:00
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
}
2020-12-16 14:08:34 +01:00
cfg, err := dns.ClientConfigFromFile(DefaultResolvConfPath)
2020-12-13 08:15:45 +01:00
if err != nil {
2020-12-17 12:27:44 +01:00
return nil, err
2020-12-13 08:15:45 +01:00
}
2020-12-17 12:27:44 +01:00
cfg.Ndots = ndots
return cfg.NameList(d), nil
2020-12-10 17:14:04 +01:00
}