diff --git a/ptrstream.go b/ptrstream.go index d39c815..6a0efb7 100644 --- a/ptrstream.go +++ b/ptrstream.go @@ -151,20 +151,41 @@ type DNSResponse struct { TTL uint32 // Add TTL field } -func lookupWithRetry(ip string, cfg *Config) (DNSResponse, error) { +func translateRcode(rcode int) string { + switch rcode { + case dns.RcodeSuccess: + return "Success" + case dns.RcodeFormatError: + return "Format Error" + case dns.RcodeServerFailure: + return "Server Failure" + case dns.RcodeNameError: // NXDOMAIN + return "No Such Domain" + case dns.RcodeNotImplemented: + return "Not Implemented" + case dns.RcodeRefused: + return "Query Refused" + default: + return fmt.Sprintf("DNS Error %d", rcode) + } +} + +func lookupWithRetry(ip string, cfg *Config) (DNSResponse, string, error) { var lastErr error + var lastServer string for i := 0; i < cfg.retries; i++ { server := cfg.getNextServer() if server == "" { - return DNSResponse{}, fmt.Errorf("no DNS servers available") + return DNSResponse{}, "", fmt.Errorf("no DNS servers available") } + lastServer = server // Create DNS message m := new(dns.Msg) arpa, err := dns.ReverseAddr(ip) if err != nil { - return DNSResponse{}, err + return DNSResponse{}, "", err } m.SetQuestion(arpa, dns.TypePTR) m.RecursionDesired = true @@ -181,15 +202,10 @@ func lookupWithRetry(ip string, cfg *Config) (DNSResponse, error) { } if r.Rcode != dns.RcodeSuccess { - lastErr = fmt.Errorf("DNS query failed with code: %d", r.Rcode) + lastErr = fmt.Errorf("%s", translateRcode(r.Rcode)) continue } - logServer := server - if idx := strings.Index(server, ":"); idx != -1 { - logServer = server[:idx] - } - // Process the response if len(r.Answer) > 0 { var names []string @@ -214,25 +230,25 @@ func lookupWithRetry(ip string, cfg *Config) (DNSResponse, error) { if isCNAME { return DNSResponse{ Names: names, - Server: logServer, + Server: server, RecordType: "CNAME", Target: strings.TrimSuffix(target, "."), TTL: ttl, - }, nil + }, server, nil } return DNSResponse{ Names: names, - Server: logServer, + Server: server, RecordType: "PTR", TTL: ttl, - }, nil + }, server, nil } } lastErr = fmt.Errorf("no PTR records found") } - return DNSResponse{}, lastErr + return DNSResponse{}, lastServer, lastErr } func reverse(ss []string) []string { @@ -324,9 +340,13 @@ func worker(jobs <-chan string, wg *sync.WaitGroup, cfg *Config, stats *Stats, t timestamp := time.Now() var response DNSResponse var err error + var server string if len(cfg.dnsServers) > 0 { - response, err = lookupWithRetry(ip, cfg) + response, server, err = lookupWithRetry(ip, cfg) + if idx := strings.Index(server, ":"); idx != -1 { + server = server[:idx] + } } else { names, err := net.LookupAddr(ip) if err == nil { @@ -339,17 +359,19 @@ func worker(jobs <-chan string, wg *sync.WaitGroup, cfg *Config, stats *Stats, t if err != nil { stats.incrementFailed() if cfg.debug { - timestamp := time.Now().Format("2006-01-02 15:04:05") errMsg := err.Error() if idx := strings.LastIndex(errMsg, ": "); idx != -1 { errMsg = errMsg[idx+2:] } - debugLine := fmt.Sprintf("[gray]%s[-] [purple]%15s[-] [gray]│[-] [red]%s[-]\n", - timestamp, + timeStr := time.Now().Format("2006-01-02 15:04:05") + line := fmt.Sprintf("[gray]%s [gray]│[-] [purple]%15s[-] [gray]│[-] [aqua]%-15s[-] [gray]│[-] [red] ERR [-] [gray]│[-] [gray]%-6s[-] [gray]│[-] [gray]%s[-]\n", + timeStr, ip, + server, + "", errMsg) app.QueueUpdateDraw(func() { - fmt.Fprint(textView, debugLine) + fmt.Fprint(textView, line) textView.ScrollToEnd() }) } @@ -359,12 +381,14 @@ func worker(jobs <-chan string, wg *sync.WaitGroup, cfg *Config, stats *Stats, t if len(response.Names) == 0 { stats.incrementFailed() if cfg.debug { - timestamp := time.Now().Format("2006-01-02 15:04:05") - debugLine := fmt.Sprintf("[gray]%s[-] [purple]%15s[-] [gray]│[-] [red]No PTR record[-]\n", - timestamp, - ip) + timeStr := time.Now().Format("2006-01-02 15:04:05") + line := fmt.Sprintf("[gray]%s [gray]│[-] [purple]%15s[-] [gray]│[-] [aqua]%-15s[-] [gray]│[-] [red] ERR [-] [gray]│[-] [gray]%-6s[-] [gray]│[-] [red]No PTR record[-]\n", + timeStr, + ip, + server, + "") app.QueueUpdateDraw(func() { - fmt.Fprint(textView, debugLine) + fmt.Fprint(textView, line) textView.ScrollToEnd() }) } @@ -385,7 +409,7 @@ func worker(jobs <-chan string, wg *sync.WaitGroup, cfg *Config, stats *Stats, t continue } - writeNDJSON(cfg, timestamp, ip, response.Server, ptr, response.RecordType, response.Target, response.TTL) + writeNDJSON(cfg, timestamp, ip, server, ptr, response.RecordType, response.Target, response.TTL) timeStr := time.Now().Format("2006-01-02 15:04:05") recordTypeColor := "[blue] PTR [-]" @@ -400,7 +424,7 @@ func worker(jobs <-chan string, wg *sync.WaitGroup, cfg *Config, stats *Stats, t line = fmt.Sprintf("[gray]%s [gray]│[-] [purple]%15s[-] [gray]│[-] [aqua]%-15s[-] [gray]│[-] %-5s [gray]│[-] %s [gray]│[-] %s\n", timeStr, ip, - response.Server, + server, recordTypeColor, colorizeTTL(response.TTL), colorizeIPInPtr(ptr, ip))