Skip to content

Instantly share code, notes, and snippets.

@mrqwer88
Last active December 24, 2015 13:17
Show Gist options
  • Save mrqwer88/619580fd86e5a8a18923 to your computer and use it in GitHub Desktop.
Save mrqwer88/619580fd86e5a8a18923 to your computer and use it in GitHub Desktop.
package main
import "fmt"
import "sort"
import "strings"
import (
"code.google.com/p/getopt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"os"
"runtime"
"sync"
"time"
)
var counter map[string]int
type ArraySortByMapValues []string
func (s ArraySortByMapValues) Len() int {
return len(s)
}
func (s ArraySortByMapValues) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s ArraySortByMapValues) Less(i, j int) bool {
return counter[s[i]] > counter[s[j]]
}
/*
apt-get install -y libpcap-dev
go get code.google.com/p/gopacket/pcap
*/
func main() {
runtime.GOMAXPROCS(2)
optInterface := getopt.StringLong("interface", 'i', "eth0", "Set our interface to sniff")
optDelay := getopt.IntLong("delay", 'd', 5, "Set output delay in seconds")
optHelp := getopt.BoolLong("help", 'h', "Print help message")
getopt.Parse()
if *optHelp {
getopt.Usage()
os.Exit(0)
}
counter = make(map[string]int)
//if handle, err := pcap.OpenLive("eth0", 1600, true, 0); err != nil {
if handle, err := pcap.OpenLive(*optInterface, 1600, true, 0); err != nil {
panic(err)
} else if err := handle.SetBPFFilter("udp dst port 53"); err != nil { // optional
panic(err)
} else {
fmt.Printf("We start sniff port 53 for upd on %s interface whith output delay %v seconds\n", *optInterface, *optDelay)
var waitGroup sync.WaitGroup
waitGroup.Add(2)
go func() {
defer waitGroup.Done()
for {
data, _, err := handle.ReadPacketData()
if err != nil {
continue
}
packet := gopacket.NewPacket(data, handle.LinkType(), gopacket.Default)
dnsLayer := packet.Layer(layers.LayerTypeDNS)
if dnsLayer == nil {
continue
}
dns_data := dnsLayer.(*layers.DNS)
if len(dns_data.Questions) == 0 {
continue
}
dns_question := dns_data.Questions[0]
domain_name := strings.ToLower(string(dns_question.Name))
if _, ok := counter[domain_name]; ok {
counter[domain_name]++
} else {
counter[domain_name] = 1
}
}
}()
go func() {
defer waitGroup.Done()
for {
time.Sleep(time.Duration(*optDelay) * time.Second)
records_count := 0
sorted_keys := make([]string, 0, len(counter))
for k := range counter {
sorted_keys = append(sorted_keys, k)
}
sort.Sort(ArraySortByMapValues(sorted_keys))
fmt.Println("\n\n\nNext iteration\n\n\n")
for _, key := range sorted_keys {
records_count++
if records_count > 50 {
break
}
fmt.Println(key, " ", counter[key])
}
}
}()
waitGroup.Wait()
}
}
@mrqwer88
Copy link
Author

mrqwer88 commented May 4, 2015

It have params now

./dns_sniffer --help
Usage: dns_sniffer [-h] [-d value] [-i value] [parameters ...]
 -d, --delay=value  Set output delay in seconds
 -h, --help         Print help message
 -i, --interface=value
                    Set our interface to sniff

By default interface - eth0. And delay 5 sec(we set delay in seconds).
Count and output in another threads now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment