split off the questions
This commit is contained in:
parent
1a81ac9c85
commit
9e2bec0041
|
@ -3,6 +3,6 @@
|
|||
# license that can be found in the LICENSE file.
|
||||
include $(GOROOT)/src/Make.inc
|
||||
TARG=q
|
||||
GOFILES=q.go fp.go lex.go
|
||||
GOFILES=q.go fp.go lex.go dns.go
|
||||
DEPS=../../
|
||||
include $(GOROOT)/src/Make.cmd
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"dns"
|
||||
)
|
||||
|
||||
// Check if the server responds at all
|
||||
func dnsAlive(l *lexer) stateFn {
|
||||
l.verbose("Alive")
|
||||
l.setString("QUERY,NOERROR,qr,aa,tc,rd,ra,ad,cd,z,1,0,0,0,do,0")
|
||||
l.setQuestion(".", dns.TypeNS, dns.ClassINET)
|
||||
|
||||
f := l.probe()
|
||||
|
||||
if f.ok() {
|
||||
return dnsDoBitMirror
|
||||
}
|
||||
l.emit(&item{itemError, f.error()})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if the server returns the DO-bit when set in the request.
|
||||
func dnsDoBitMirror(l *lexer) stateFn {
|
||||
l.verbose("DoBitMirror")
|
||||
// The important part here is that the DO bit is on in the reply
|
||||
l.setString("QUERY,NOERROR,qr,aa,tc,RD,ra,ad,cd,z,1,0,0,0,DO,0")
|
||||
l.setQuestion(".", dns.TypeNS, dns.ClassINET)
|
||||
|
||||
f := l.probe()
|
||||
if !f.Do {
|
||||
l.emit(&item{itemSoftware, NSD})
|
||||
return nil
|
||||
}
|
||||
l.emit(&item{itemSoftware, BIND})
|
||||
return nil
|
||||
}
|
|
@ -17,7 +17,7 @@ const (
|
|||
// Vendors
|
||||
ISC = "ISC"
|
||||
NLNETLABS = "NLnet Labs"
|
||||
MICROSOFT = "Microsoft"
|
||||
MICROSOFT = "Microsoft"
|
||||
)
|
||||
|
||||
func startParse(addr string) {
|
||||
|
@ -27,6 +27,7 @@ func startParse(addr string) {
|
|||
fp: new(fingerprint),
|
||||
items: make(chan item),
|
||||
state: dnsAlive,
|
||||
debug: true,
|
||||
}
|
||||
|
||||
l.run()
|
||||
|
@ -54,22 +55,23 @@ func sendProbe(c *dns.Client, addr string, f *fingerprint, q dns.Question) *fing
|
|||
|
||||
// This leads to strings like: "QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,1,DO,4096"
|
||||
type fingerprint struct {
|
||||
Error os.Error
|
||||
Opcode int
|
||||
Rcode int
|
||||
Response bool
|
||||
Authoritative bool
|
||||
Truncated bool
|
||||
RecursionDesired bool
|
||||
AuthenticatedData bool
|
||||
CheckingDisabled bool
|
||||
Zero bool
|
||||
Question int
|
||||
Answer int
|
||||
Ns int
|
||||
Extra int
|
||||
Do bool
|
||||
UDPSize int
|
||||
Error os.Error
|
||||
Opcode int
|
||||
Rcode int
|
||||
Response bool
|
||||
Authoritative bool
|
||||
Truncated bool
|
||||
RecursionDesired bool
|
||||
RecursionAvailable bool
|
||||
AuthenticatedData bool
|
||||
CheckingDisabled bool
|
||||
Zero bool
|
||||
Question int
|
||||
Answer int
|
||||
Ns int
|
||||
Extra int
|
||||
Do bool
|
||||
UDPSize int
|
||||
}
|
||||
|
||||
// String creates a (short) string representation of a dns message.
|
||||
|
@ -86,6 +88,7 @@ func (f *fingerprint) String() string {
|
|||
s += valueOfBool(f.Authoritative, ",aa")
|
||||
s += valueOfBool(f.Truncated, ",tc")
|
||||
s += valueOfBool(f.RecursionDesired, ",rd")
|
||||
s += valueOfBool(f.RecursionAvailable, ",ra")
|
||||
s += valueOfBool(f.AuthenticatedData, ",ad")
|
||||
s += valueOfBool(f.CheckingDisabled, ",cd")
|
||||
s += valueOfBool(f.Zero, ",z")
|
||||
|
@ -129,28 +132,33 @@ func (f *fingerprint) setString(str string) {
|
|||
f.RecursionDesired = true
|
||||
}
|
||||
case 6:
|
||||
f.RecursionAvailable = false
|
||||
if s == strings.ToUpper("ra") {
|
||||
f.RecursionAvailable = true
|
||||
}
|
||||
case 7:
|
||||
f.AuthenticatedData = false
|
||||
if s == strings.ToUpper("ad") {
|
||||
f.AuthenticatedData = true
|
||||
}
|
||||
case 7:
|
||||
case 8:
|
||||
f.CheckingDisabled = false
|
||||
if s == strings.ToUpper("cd") {
|
||||
f.CheckingDisabled = true
|
||||
}
|
||||
case 8:
|
||||
case 9:
|
||||
f.Zero = false
|
||||
if s == strings.ToUpper("z") {
|
||||
f.Zero = true
|
||||
}
|
||||
case 9, 10, 11, 12:
|
||||
case 10, 11, 12, 13:
|
||||
// Can not set content of the message
|
||||
case 13:
|
||||
case 14:
|
||||
f.Do = false
|
||||
if s == strings.ToUpper("do") {
|
||||
f.Do = true
|
||||
}
|
||||
case 14:
|
||||
case 15:
|
||||
f.UDPSize = 0
|
||||
f.UDPSize = valueOfString(s)
|
||||
default:
|
||||
|
@ -190,6 +198,7 @@ func msgToFingerprint(m *dns.Msg) *fingerprint {
|
|||
f.Authoritative = h.Authoritative
|
||||
f.Truncated = h.Truncated
|
||||
f.RecursionDesired = h.RecursionDesired
|
||||
f.RecursionAvailable = h.RecursionAvailable
|
||||
f.AuthenticatedData = h.AuthenticatedData
|
||||
f.CheckingDisabled = h.CheckingDisabled
|
||||
f.Zero = h.Zero
|
||||
|
|
|
@ -34,10 +34,15 @@ type lexer struct {
|
|||
q dns.Question // question to ask.
|
||||
items chan item // channel of scanned items.
|
||||
state stateFn // the next function to enter.
|
||||
debug bool // if true, the fingerprints are printed.
|
||||
}
|
||||
|
||||
func (l *lexer) probe() *fingerprint {
|
||||
return sendProbe(l.client, l.addr, l.fp, l.q)
|
||||
f := sendProbe(l.client, l.addr, l.fp, l.q)
|
||||
if l.debug {
|
||||
fmt.Printf(" QR fp: %s\n", f)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (l *lexer) emit(i *item) {
|
||||
|
@ -46,6 +51,9 @@ func (l *lexer) emit(i *item) {
|
|||
|
||||
func (l *lexer) setString(s string) {
|
||||
l.fp.setString(s)
|
||||
if l.debug {
|
||||
fmt.Printf(" Q fp: %s\n", s)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *lexer) setQuestion(name string, t uint16, c uint16) {
|
||||
|
@ -62,38 +70,5 @@ func (l *lexer) run() {
|
|||
}
|
||||
|
||||
func (l *lexer) verbose(s string) {
|
||||
fmt.Printf("running: dns%s\n", s)
|
||||
}
|
||||
|
||||
// "Lexer" functions, prefixed with dns
|
||||
|
||||
// Check if the server responds at all
|
||||
func dnsAlive(l *lexer) stateFn {
|
||||
l.verbose("Alive")
|
||||
l.setString("QUERY,NOERROR,qr,aa,tc,rd,ad,cd,z,1,0,0,0,do,0")
|
||||
l.setQuestion(".", dns.TypeNS, dns.ClassINET)
|
||||
|
||||
f := l.probe()
|
||||
|
||||
if f.ok() {
|
||||
return dnsDoBitMirror
|
||||
}
|
||||
l.emit(&item{itemError, f.error()})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if the server returns the DO-bit when set in the request.
|
||||
func dnsDoBitMirror(l *lexer) stateFn {
|
||||
l.verbose("DoBitMirror")
|
||||
// The important part here is that the DO bit is on in the reply
|
||||
l.setString("QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,0,DO,0")
|
||||
l.setQuestion(".", dns.TypeNS, dns.ClassINET)
|
||||
|
||||
f := l.probe()
|
||||
if !f.Do {
|
||||
l.emit(&item{itemSoftware, NSD})
|
||||
return nil
|
||||
}
|
||||
l.emit(&item{itemSoftware, BIND})
|
||||
return nil
|
||||
fmt.Printf("running: dns%s\n", s)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue