split off the questions

This commit is contained in:
Miek Gieben 2011-09-20 14:59:28 +02:00
parent 1a81ac9c85
commit 9e2bec0041
4 changed files with 78 additions and 58 deletions

View File

@ -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

36
_examples/q/dns.go Normal file
View File

@ -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
}

View File

@ -27,6 +27,7 @@ func startParse(addr string) {
fp: new(fingerprint),
items: make(chan item),
state: dnsAlive,
debug: true,
}
l.run()
@ -61,6 +62,7 @@ type fingerprint struct {
Authoritative bool
Truncated bool
RecursionDesired bool
RecursionAvailable bool
AuthenticatedData bool
CheckingDisabled bool
Zero bool
@ -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

View File

@ -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) {
@ -64,36 +72,3 @@ 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
}