Created
November 18, 2016 12:54
-
-
Save mathyourlife/d5c33e53400a0289fd0ae5210d4e47a4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on | |
// https://raw.githubusercontent.com/bmorton/dnswatch/0eec21738a7f9b3786c43e6c13c2d6c32cc60f73/dnswatch.go | |
package main | |
import ( | |
"flag" | |
"fmt" | |
"time" | |
"github.com/google/gopacket" | |
"github.com/google/gopacket/layers" | |
"github.com/google/gopacket/pcap" | |
) | |
func recordName(dnsType layers.DNSType) string { | |
if dnsType == layers.DNSTypeA { | |
return "A" | |
} else if dnsType == layers.DNSTypeNS { | |
return "NS" | |
} else if dnsType == layers.DNSTypeMD { | |
return "MD" | |
} else if dnsType == layers.DNSTypeMF { | |
return "MF" | |
} else if dnsType == layers.DNSTypeCNAME { | |
return "CNAME" | |
} else if dnsType == layers.DNSTypeSOA { | |
return "SOA" | |
} else if dnsType == layers.DNSTypeMB { | |
return "MB" | |
} else if dnsType == layers.DNSTypeMG { | |
return "MG" | |
} else if dnsType == layers.DNSTypeMR { | |
return "MR" | |
} else if dnsType == layers.DNSTypeNULL { | |
return "NULL" | |
} else if dnsType == layers.DNSTypeWKS { | |
return "WKS" | |
} else if dnsType == layers.DNSTypePTR { | |
return "PTR" | |
} else if dnsType == layers.DNSTypeHINFO { | |
return "HINFO" | |
} else if dnsType == layers.DNSTypeMINFO { | |
return "MINFO" | |
} else if dnsType == layers.DNSTypeMX { | |
return "MX" | |
} else if dnsType == layers.DNSTypeTXT { | |
return "TXT" | |
} else if dnsType == layers.DNSTypeAAAA { | |
return "AAAA" | |
} else if dnsType == layers.DNSTypeSRV { | |
return "SRV" | |
} | |
return "UNKNOWN" | |
} | |
func main() { | |
var deviceInterface string | |
flag.StringVar(&deviceInterface, "interface", "wlan0", "device interface to listen for DNS packets") | |
flag.Parse() | |
handle, err := pcap.OpenLive(deviceInterface, 65535, true, 1000) | |
if err != nil { | |
panic(err) | |
} | |
err = handle.SetBPFFilter("port 53") | |
if err != nil { | |
panic(err) | |
} | |
fmt.Printf("Watching for DNS packets on %s...\n", deviceInterface) | |
packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) | |
packetChan := packetSource.Packets() | |
for { | |
select { | |
case packet := <-packetChan: | |
handlePacket(packet) | |
} | |
} | |
} | |
// From ANY query | |
// &layers.DNS{BaseLayer:layers.BaseLayer{ | |
// Contents:[]uint8{0x60, 0x70, 0x81, 0x80, 0x0, 0x1, 0x0, 0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x77, 0x77, 0x77, 0x6, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3, 0x63, 0x6f, 0x6d, 0x0, 0x0, 0xff, 0x0, 0x1, 0xc0, 0xc, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x26, 0x0, 0x4, 0xac, 0xd9, 0x4, 0x44, 0xc0, 0xc, 0x0, 0x1c, 0x0, 0x1, 0x0, 0x0, 0x0, 0x25, 0x0, 0x10, 0x26, 0x7, 0xf8, 0xb0, 0x40, 0x6, 0x8, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4, 0x0, 0x0, 0x29, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, | |
// Payload:[]uint8(nil)}, | |
// ID:0x6070, QR:true, OpCode:0x0, AA:false, TC:false, RD:true, RA:true, Z:0x0, | |
// ResponseCode:0x0, QDCount:0x1, | |
// ANCount:0x2, NSCount:0x0, | |
// ARCount:0x1, Questions:[]layers.DNSQuestion{ | |
// layers.DNSQuestion{Name:[]uint8{0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d}, Type:0xff, Class:0x1}}, | |
// Answers:[]layers.DNSResourceRecord{ | |
// layers.DNSResourceRecord{Name:[]uint8{0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d}, Type:0x1, | |
// Class:0x1, TTL:0x26, DataLength:0x4, | |
// Data:[]uint8{0xac, 0xd9, 0x4, 0x44}, IP:net.IP{0xac, 0xd9, 0x4, 0x44}, NS:[]uint8(nil), | |
// CNAME:[]uint8(nil), PTR:[]uint8(nil), | |
// TXTs:[][]uint8(nil), | |
// SOA:layers.DNSSOA{MName:[]uint8(nil), | |
// RName:[]uint8(nil), Serial:0x0, | |
// Refresh:0x0, Retry:0x0, Expire:0x0, Minimum:0x0}, | |
// SRV:layers.DNSSRV{Priority:0x0, Weight:0x0, Port:0x0, | |
// Name:[]uint8(nil)}, | |
// MX:layers.DNSMX{Preference:0x0, Name:[]uint8(nil)}, TXT:[]uint8(nil)}, | |
// layers.DNSResourceRecord{Name:[]uint8{0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d}, | |
// Type:0x1c, Class:0x1, TTL:0x25, DataLength:0x10, | |
// Data:[]uint8{0x26, 0x7, 0xf8, 0xb0, 0x40, 0x6, 0x8, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4}, | |
// IP:net.IP{0x26, 0x7, 0xf8, 0xb0, 0x40, 0x6, 0x8, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4}, | |
// NS:[]uint8(nil), CNAME:[]uint8(nil), PTR:[]uint8(nil), TXTs:[][]uint8(nil), | |
// SOA:layers.DNSSOA{MName:[]uint8(nil), RName:[]uint8(nil), Serial:0x0, Refresh:0x0, Retry:0x0, Expire:0x0, Minimum:0x0}, | |
// SRV:layers.DNSSRV{Priority:0x0, Weight:0x0, Port:0x0, Name:[]uint8(nil)}, | |
// MX:layers.DNSMX{Preference:0x0, Name:[]uint8(nil)}, TXT:[]uint8(nil)}}, | |
// Authorities:[]layers.DNSResourceRecord(nil), | |
// Additionals:[]layers.DNSResourceRecord{layers.DNSResourceRecord{Name:[]uint8(nil), Type:0x29, | |
// Class:0x1000, TTL:0x0, DataLength:0x0, Data:[]uint8{}, IP:net.IP(nil), NS:[]uint8(nil), | |
// CNAME:[]uint8(nil), PTR:[]uint8(nil), TXTs:[][]uint8(nil), | |
// SOA:layers.DNSSOA{MName:[]uint8(nil), RName:[]uint8(nil), Serial:0x0, Refresh:0x0, Retry:0x0, Expire:0x0, Minimum:0x0}, | |
// SRV:layers.DNSSRV{Priority:0x0, Weight:0x0, Port:0x0, Name:[]uint8(nil)}, | |
// MX:layers.DNSMX{Preference:0x0, Name:[]uint8(nil)}, TXT:[]uint8(nil)}}, | |
// buffer:[]uint8{0x2e, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d}} | |
func handlePacket(packet gopacket.Packet) { | |
metadata := packet.Metadata() | |
dnsLayer := packet.Layer(layers.LayerTypeDNS) | |
dns, _ := dnsLayer.(*layers.DNS) | |
if len(dns.Answers) == 0 { | |
return | |
} | |
fmt.Printf("%#v\n", dns) | |
for _, question := range dns.Questions { | |
if question.Type == layers.DNSTypeA || question.Type == layers.DNSTypeAAAA { | |
fmt.Printf("%s - %s [%d]\n", metadata.Timestamp.Format(time.ANSIC), string(question.Name), dns.ID) | |
} | |
} | |
for _, answer := range dns.Answers { | |
fmt.Printf("\t\t\t -> %s %s\n", recordName(answer.Type), answer.String()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment