<commit_before>package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"net"
	"os"
	"sync"
)

type SubnetIterator struct {
	Current net.IP
	Net net.IPNet
}

func NewSubnetIterator(s string) (SubnetIterator, error) {
	sni := SubnetIterator{}
	_, ipnet, err := net.ParseCIDR(s)
	if err != nil {
		return sni, err
	}
	sni.Net = *ipnet

	sni.Current = ipnet.IP.Mask(ipnet.Mask)
	if err != nil {
		return sni, err
	}
	
	return sni, nil
}

func (sni *SubnetIterator) Next() bool {
	var intIP int32
	buf := bytes.NewBuffer(sni.Current)
	if err := binary.Read(buf, binary.BigEndian, &intIP); err != nil {
		panic("Internal error converting IP to integer")
	}
	intIP += 1

	buf = new(bytes.Buffer)
	if err := binary.Write(buf, binary.BigEndian, intIP); err != nil {
		panic("Internal error converting integer to IP")
	}
	ip := buf.Bytes()
	
	if !sni.Net.Contains(ip) {
		return false
	}

	sni.Current = ip
	return true
}

type WorkerPool struct {
	inChan chan interface{}
	wg sync.WaitGroup
	jobFunction func(interface{})
}

func NewWorkerPool (workers int, jobFunction func(interface{})) *WorkerPool {
	wp := &WorkerPool{jobFunction: jobFunction}
	wp.inChan = make(chan interface{}, 100)
	for i := 0; i < workers; i++ {
		wp.wg.Add(1)
		go wp.worker()
	}
	
	return wp
}

func (wp *WorkerPool) AddJob(job interface{}) {
	wp.inChan <- job
}

func (wp *WorkerPool) Shutdown() {
	close(wp.inChan)
	wp.wg.Wait()
}

func (wp *WorkerPool) worker() {
	for in := <- wp.inChan; in != nil; in = <- wp.inChan {
		wp.jobFunction(in)
	}
	wp.wg.Done()
}

func reverseLookupJob(in interface{}) {
	ip := in.(net.IP)
	addrs, err := net.LookupAddr(ip.String())
	if err != nil {
		// fmt.Println(err)
	} else {
		fmt.Println(ip, addrs[0])
	}
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage: reversemop 1.2.3.4/24")
		return
	}
	
	wp := NewWorkerPool(10, reverseLookupJob)
	sni, err := NewSubnetIterator(os.Args[1])
	if err != nil {
		fmt.Println(err)
		return
	}

	wp.AddJob(sni.Current)
	for sni.Next() {
		wp.AddJob(sni.Current)
	}
	
	wp.Shutdown()
}
<commit_msg>Use github.com/miekg/dns library<commit_after>package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"net"
	"os"
	"sync"
	"github.com/miekg/dns"
)

var dnsConf *dns.ClientConfig

type SubnetIterator struct {
	Current net.IP
	Net net.IPNet
}

func NewSubnetIterator(s string) (SubnetIterator, error) {
	sni := SubnetIterator{}
	_, ipnet, err := net.ParseCIDR(s)
	if err != nil {
		return sni, err
	}
	sni.Net = *ipnet

	sni.Current = ipnet.IP.Mask(ipnet.Mask)
	if err != nil {
		return sni, err
	}
	
	return sni, nil
}

func (sni *SubnetIterator) Next() bool {
	var intIP int32
	buf := bytes.NewBuffer(sni.Current)
	if err := binary.Read(buf, binary.BigEndian, &intIP); err != nil {
		panic("Internal error converting IP to integer")
	}
	intIP += 1

	buf = new(bytes.Buffer)
	if err := binary.Write(buf, binary.BigEndian, intIP); err != nil {
		panic("Internal error converting integer to IP")
	}
	ip := buf.Bytes()
	
	if !sni.Net.Contains(ip) {
		return false
	}

	sni.Current = ip
	return true
}

type WorkerPool struct {
	inChan chan interface{}
	wg sync.WaitGroup
	jobFunction func(interface{})
}

func NewWorkerPool (workers int, jobFunction func(interface{})) *WorkerPool {
	wp := &WorkerPool{jobFunction: jobFunction}
	wp.inChan = make(chan interface{}, 100)
	for i := 0; i < workers; i++ {
		wp.wg.Add(1)
		go wp.worker()
	}
	
	return wp
}

func (wp *WorkerPool) AddJob(job interface{}) {
	wp.inChan <- job
}

func (wp *WorkerPool) Shutdown() {
	close(wp.inChan)
	wp.wg.Wait()
}

func (wp *WorkerPool) worker() {
	for in := <- wp.inChan; in != nil; in = <- wp.inChan {
		wp.jobFunction(in)
	}
	wp.wg.Done()
}

func reverseLookupJob(in interface{}) {
	ip := in.(net.IP)
	m := new(dns.Msg)
	c := new(dns.Client)
	
	rname, _ :=  dns.ReverseAddr(ip.String())
	m.SetQuestion(rname, dns.TypePTR)
	m.MsgHdr.RecursionDesired = true
	
	r, err := c.Exchange(m, dnsConf.Servers[0] + ":" + dnsConf.Port)
	if err != nil {
		fmt.Println(err)
		return
	}
	if r.Rcode != dns.RcodeSuccess {
		fmt.Println("Failed: ", r.Rcode)
		return
	}
	
	for _, a := range r.Answer {
		ptr := a.(*dns.RR_PTR)
		fmt.Printf("%v\n", ptr.Ptr)
	}
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage: reversemop 172.16.31.10/24")
		return
	}
	
	var err error
	dnsConf, err = dns.ClientConfigFromFile("/etc/resolv.conf")
	if err != nil {
		fmt.Println(err)
		return
	}
	
		
	wp := NewWorkerPool(10, reverseLookupJob)
	sni, err := NewSubnetIterator(os.Args[1])
	if err != nil {
		fmt.Println(err)
		return
	}

	wp.AddJob(sni.Current)
	for sni.Next() {
		wp.AddJob(sni.Current)
	}
	
	wp.Shutdown()
}

{'fraction_non_alphanumeric': 0.15987055016181229, 'fraction_numerical': 0.009277238403451996, 'mean_word_length': 3.52734375, 'pattern_counts': {'":': 1, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '85331', 'n_tokens_mistral': 2012, 'n_tokens_neox': 1877, 'n_words': 433}