doggo/cmd/output.go

144 lines
3.3 KiB
Go
Raw Normal View History

2020-12-12 11:57:13 +01:00
package main
2020-12-12 15:10:28 +01:00
import (
2020-12-13 05:04:53 +01:00
"encoding/json"
2020-12-12 15:10:28 +01:00
"fmt"
2020-12-13 04:17:07 +01:00
"os"
2020-12-12 15:10:28 +01:00
"strconv"
"github.com/fatih/color"
"github.com/miekg/dns"
"github.com/mr-karan/doggo/pkg/resolvers"
2020-12-13 04:17:07 +01:00
"github.com/olekukonko/tablewriter"
2020-12-12 15:10:28 +01:00
)
2020-12-13 05:04:53 +01:00
// Output has a list of fields which are produced for the output
type Output struct {
2020-12-13 08:15:45 +01:00
Name string `json:"name"`
Type string `json:"type"`
Class string `json:"class"`
TTL string `json:"ttl"`
Address string `json:"address"`
TimeTaken string `json:"rtt"`
Nameserver string `json:"nameserver"`
2020-12-13 05:04:53 +01:00
}
type Query struct {
Name string `json:"name"`
Type string `json:"type"`
Class string `json:"class"`
}
type Response struct {
Output []Output `json:"answers"`
Queries []Query `json:"queries"`
}
type JSONResponse struct {
Response `json:"responses"`
}
func (hub *Hub) outputJSON(out []Output, msgs []resolvers.Response) {
// get the questions
queries := make([]Query, 0, len(msgs))
2020-12-13 09:26:38 +01:00
for _, ques := range hub.Questions {
q := Query{
Name: ques.Name,
Type: dns.ClassToString[ques.Qtype],
Class: dns.ClassToString[ques.Qclass],
2020-12-13 05:04:53 +01:00
}
2020-12-13 09:26:38 +01:00
queries = append(queries, q)
2020-12-13 05:04:53 +01:00
}
2020-12-13 09:26:38 +01:00
2020-12-13 05:04:53 +01:00
resp := JSONResponse{
Response{
Output: out,
Queries: queries,
},
}
res, err := json.Marshal(resp)
if err != nil {
hub.Logger.WithError(err).Error("unable to output data in JSON")
hub.Logger.Exit(-1)
}
fmt.Printf("%s", res)
}
func (hub *Hub) outputTerminal(out []Output) {
2020-12-12 15:10:28 +01:00
green := color.New(color.FgGreen).SprintFunc()
blue := color.New(color.FgBlue).SprintFunc()
2020-12-13 04:17:07 +01:00
table := tablewriter.NewWriter(os.Stdout)
header := []string{"Name", "Type", "Class", "TTL", "Address"}
if hub.QueryFlags.DisplayTimeTaken {
header = append(header, "Time Taken")
}
2020-12-13 09:26:38 +01:00
table.SetAutoWrapText(false)
table.SetAutoFormatHeaders(true)
2020-12-13 04:17:07 +01:00
table.SetHeader(header)
2020-12-13 05:04:53 +01:00
for _, o := range out {
output := []string{green(o.Name), blue(o.Type), o.Class, o.TTL, o.Address}
// Print how long it took
if hub.QueryFlags.DisplayTimeTaken {
output = append(output, o.TimeTaken)
}
table.Append(output)
}
table.Render()
}
// Output takes a list of `dns.Answers` and based
// on the output format specified displays the information.
func (hub *Hub) Output(responses []resolvers.Response) {
out := collectOutput(responses)
2020-12-13 09:26:38 +01:00
if len(out) == 0 {
hub.Logger.Info("No records found")
hub.Logger.Exit(0)
}
2020-12-13 05:04:53 +01:00
if hub.QueryFlags.ShowJSON {
hub.outputJSON(out, responses)
} else {
hub.outputTerminal(out)
}
}
func collectOutput(responses []resolvers.Response) []Output {
2020-12-13 09:26:38 +01:00
var out []Output
2020-12-13 05:04:53 +01:00
// gather Output from the DNS Messages
2020-12-12 15:10:28 +01:00
for _, r := range responses {
2020-12-13 05:04:53 +01:00
var addr string
2020-12-12 15:10:28 +01:00
for _, a := range r.Message.Answer {
switch t := a.(type) {
case *dns.A:
2020-12-13 05:04:53 +01:00
addr = t.A.String()
2020-12-13 09:26:38 +01:00
case *dns.AAAA:
addr = t.AAAA.String()
case *dns.CNAME:
addr = t.Target
case *dns.MX:
addr = strconv.Itoa(int(t.Preference)) + " " + t.Mx
case *dns.SOA:
addr = t.String()
2020-12-12 15:10:28 +01:00
}
2020-12-13 09:26:38 +01:00
2020-12-12 15:10:28 +01:00
h := a.Header()
2020-12-13 05:04:53 +01:00
name := h.Name
2020-12-12 15:10:28 +01:00
qclass := dns.Class(h.Class).String()
ttl := strconv.FormatInt(int64(h.Ttl), 10) + "s"
2020-12-13 05:04:53 +01:00
qtype := dns.Type(h.Rrtype).String()
rtt := fmt.Sprintf("%dms", r.RTT.Milliseconds())
o := Output{
2020-12-13 08:15:45 +01:00
Name: name,
Type: qtype,
TTL: ttl,
Class: qclass,
Address: addr,
TimeTaken: rtt,
Nameserver: r.Nameserver,
2020-12-13 04:17:07 +01:00
}
2020-12-13 05:04:53 +01:00
out = append(out, o)
2020-12-12 15:10:28 +01:00
}
}
2020-12-13 05:04:53 +01:00
return out
2020-12-12 15:10:28 +01:00
}