Skip to content

Commit

Permalink
Added different usage options
Browse files Browse the repository at this point in the history
  • Loading branch information
topscoder committed Aug 13, 2023
1 parent 80ca4ad commit db16f59
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 25 deletions.
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ptr - Find hostname of IP addresses
# IP PTR Lookup Script

-
This is a simple Go script that performs PTR (reverse DNS) lookups for IP addresses. It can handle single IP addresses, IP addresses from a file, or IP addresses provided via stdin.

## Installation

Expand All @@ -11,3 +11,37 @@ go install github.com/topscoder/ptr@latest
```

This will install the ptr script as an executable in your Go bin directory.

## Usage

Run the script with different options:

* To look up a single IP address:

```shell
ptr 8.8.8.8
```

* To process IP addresses from a file (one IP address per line):

```shell
ptr ips.txt
```

* To provide IP addresses via stdin (press Ctrl + D to signal the end of input):

```shell
cat ips.txt | ptr -
```

Enjoy the PTR lookup results!

## License

This project is licensed under the MIT License.

Feel free to fork the repository, make improvements, and submit pull requests!

## Acknowledgements

This script was inspired by the need for a simple tool to perform PTR lookups for multiple IP addresses quickly.
161 changes: 138 additions & 23 deletions ptr.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,151 @@
package main

import (
"fmt"
"net"
"os"
"strings"
"bufio"
"fmt"
"net"
"os"
"strings"
"sync"
)

func main() {
args := os.Args[1:]
args := os.Args[1:]

if len(args) != 1 {
fmt.Println("Usage: ptr <ip_address>")
return
}
if len(args) < 1 {
printUsage()
return
}

ip := args[0]
arg := args[0]

ptrDomainName, err := net.LookupAddr(ip)
if err != nil {
fmt.Println("No PTR record found for", ip)
return
}
if isFile(arg) {
processFile(arg)
} else if arg == "-" {
processStdin()
} else {
processSingleIP(arg)
}
}

func printUsage() {
fmt.Println("Usage:")
fmt.Println(" ptr <ip_address_or_input_file>")
fmt.Println()
fmt.Println("Options:")
fmt.Println(" <ip_address_or_input_file> Provide an IP address, an input file with one IP address per line, or use '-' to read IP addresses from stdin.")
}

func isFile(path string) bool {
info, err := os.Stat(path)
if err != nil {
return false
}
return !info.IsDir()
}

func processFile(filePath string) {
file, err := os.Open(filePath)
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()

scanner := bufio.NewScanner(file)
var wg sync.WaitGroup
ipChannel := make(chan string)

// Start worker goroutines
for i := 0; i < 10; i++ { // Adjust the number of goroutines as needed
wg.Add(1)
go processIPs(ipChannel, &wg)
}

// Send IPs to worker goroutines through channel
for scanner.Scan() {
ip := strings.TrimSpace(scanner.Text())
if ip != "" {
ipChannel <- ip
}
}
close(ipChannel)

wg.Wait()

if err := scanner.Err(); err != nil {
fmt.Println("Error reading file:", err)
}
}

func processStdin() {
scanner := bufio.NewScanner(os.Stdin)
var wg sync.WaitGroup
ipChannel := make(chan string)

// Start worker goroutines
for i := 0; i < 10; i++ { // Adjust the number of goroutines as needed
wg.Add(1)
go processIPs(ipChannel, &wg)
}

// Send IPs to worker goroutines through channel
for scanner.Scan() {
ip := strings.TrimSpace(scanner.Text())
if ip != "" {
ipChannel <- ip
}
}
close(ipChannel)

wg.Wait()

if err := scanner.Err(); err != nil {
fmt.Println("Error reading input:", err)
}
}

func processSingleIP(ip string) {
var wg sync.WaitGroup
ipChannel := make(chan string)

// Start worker goroutines
for i := 0; i < 10; i++ { // Adjust the number of goroutines as needed
wg.Add(1)
go processIPs(ipChannel, &wg)
}

// Send the single IP to worker goroutines through channel
ipChannel <- ip
close(ipChannel)

wg.Wait()
}

func processIPs(ipChannel <-chan string, wg *sync.WaitGroup) {
defer wg.Done()

for ip := range ipChannel {
ptrDomainNames, err := net.LookupAddr(ip)
if err != nil {
fmt.Printf("%s\t%v\n", ip, err)
continue
}

var cleanedDomainNames []string

for _, ptrDomainName := range ptrDomainNames {
// Remove the brackets from the PTR domain name.
ptrDomainName = strings.Trim(ptrDomainName, "[")

// Remove the brackets from the PTR domain name.
ptrDomainName = strings.Trim(ptrDomainName, "[")
ptrDomainName = strings.Trim(ptrDomainName, "]")
// Remove the last character if it is a dot.
if ptrDomainName[len(ptrDomainName)-1] == '.' {
ptrDomainName = ptrDomainName[:len(ptrDomainName)-1]
}

// Remove the last character if it is a dot.
if ptrDomainName[len(ptrDomainName)-1] == '.' {
ptrDomainName = ptrDomainName[:len(ptrDomainName)-1]
}
cleanedDomainNames = append(cleanedDomainNames, ptrDomainName)
}

fmt.Println(ptrDomainName)
fmt.Printf("%s\t%s\n", ip, strings.Join(cleanedDomainNames, "\n"))
}
}

0 comments on commit db16f59

Please sign in to comment.