diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..016e197 --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2023, acidvegas + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md index 724d6e8..5f8633c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,53 @@ -# massrdns -dynamic reverse dns lookup with rotating servers +# MASSRDNS + +## Reverse DNS Lookup Tool + +This tool provides an efficient way to perform reverse DNS lookups on IP addresses, especially useful for large IP ranges. It uses concurrent workers and distributes the work among them to achieve faster results. + +### Building the Project + +1. Clone the repository: + +``` +git clone https://github.com/acidvegas/massrns +cd massrdns +``` + +2. Build the project: + +``` +go build -o massrdns +``` + +This will produce an executable named `massrdns`. + +### Usage + +The tool requires two main arguments: + +- `-cidr`: The IP address CIDR range you want to perform reverse DNS lookup on. +- `-dnsfile`: The path to a file containing DNS servers, one per line. + +Optional arguments: + +- `-concurrency`: The number of concurrent workers for reverse DNS lookup. Default is 10. + +Example: + +``` +./rdns_lookup -cidr "192.168.0.0/24" -dnsfile "dns_servers.txt" +``` + +### DNS Servers File Format + +The file should contain one DNS server per line, e.g.: + +``` +8.8.8.8:53 +1.1.1.1:53 +``` + +___ + +###### Mirrors +[acid.vegas](https://git.acid.vegas/massrdns) • [GitHub](https://github.com/acidvegas/massrdns) • [GitLab](https://gitlab.com/acidvegas/massrdns) • [SuperNETs](https://git.supernets.org/acidvegas/massrdns) diff --git a/massrdns.go b/massrdns.go new file mode 100644 index 0000000..0938e15 --- /dev/null +++ b/massrdns.go @@ -0,0 +1,190 @@ +package main + +import ( + "bufio" + "context" + "flag" + "fmt" + "math/rand" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var dnsServers []string + +func loadDNSServersFromFile(filePath string) error { + file, err := os.Open(filePath) + if err != nil { + return err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + server := scanner.Text() + + // Check if the server contains a port + if strings.Contains(server, ":") { + host, port, err := net.SplitHostPort(server) + if err != nil { + return fmt.Errorf("invalid IP:port format for %s", server) + } + if net.ParseIP(host) == nil { + return fmt.Errorf("invalid IP address in %s", server) + } + if _, err := strconv.Atoi(port); err != nil { + return fmt.Errorf("invalid port in %s", server) + } + } else { + if net.ParseIP(server) == nil { + return fmt.Errorf("invalid IP address %s", server) + } + server += ":53" // Default to port 53 if not specified + } + + dnsServers = append(dnsServers, server) + } + return scanner.Err() +} + +func reverseDNSLookup(ip string, server string) string { + ctx := context.Background() + + resolver := &net.Resolver{ + PreferGo: true, + Dial: func(ctx context.Context, network, address string) (net.Conn, error) { + d := net.Dialer{} + return d.DialContext(ctx, network, server) + }, + } + + names, err := resolver.LookupAddr(ctx, ip) + if err != nil { + return fmt.Sprintf("%s | %s | Error: %s", time.Now().Format("03:04:05 PM"), server, err) + } + + if len(names) == 0 { + return fmt.Sprintf("%s | %s | No PTR records", time.Now().Format("03:04:05 PM"), server) + } + return fmt.Sprintf("%s | %s | %s", time.Now().Format("03:04:05 PM"), server, names[0]) +} + +func worker(cidr *net.IPNet, resultsChan chan string) { + for ip := make(net.IP, len(cidr.IP)); copy(ip, cidr.IP) != 0; incrementIP(ip) { + if !cidr.Contains(ip) { + break + } + randomServer := dnsServers[rand.Intn(len(dnsServers))] + result := reverseDNSLookup(ip.String(), randomServer) + resultsChan <- result + } +} + +func splitCIDR(cidr string, parts int) ([]*net.IPNet, error) { + ip, ipNet, err := net.ParseCIDR(cidr) + if err != nil { + return nil, err + } + + maskSize, _ := ipNet.Mask.Size() + newMaskSize := maskSize + for ; (1 << uint(newMaskSize-maskSize)) < parts; newMaskSize++ { + if newMaskSize > 32 { + return nil, fmt.Errorf("too many parts; cannot split further") + } + } + + var subnets []*net.IPNet + for i := 0; i < parts; i++ { + subnets = append(subnets, &net.IPNet{ + IP: ip, + Mask: net.CIDRMask(newMaskSize, 32), + }) + incrementIPBy(ip, 1<= 0; j-- { + ip[j]++ + if ip[j] > 0 { + break + } + } +} + +func incrementIPBy(ip net.IP, count int) { + for count > 0 { + incrementIP(ip) + count-- + } +}