It is working now

This commit is contained in:
Miek Gieben 2011-09-20 10:04:42 +02:00
parent 84c1eba6b7
commit 8e71248212
2 changed files with 48 additions and 34 deletions

View File

@ -20,22 +20,22 @@ const (
) )
func startParse(addr string) { func startParse(addr string) {
l := &lexer { l := &lexer{
addr: addr, addr: addr,
client: dns.NewClient(), client: dns.NewClient(),
fp: new(fingerprint), fp: new(fingerprint),
items: make(chan item), items: make(chan item),
state: lexAlive, state: dnsAlive,
} }
l.run() l.run()
// Not completely sure about this code.. // Not completely sure about this code..
for { for {
item := <-l.items item := <-l.items
fmt.Printf("%v\n", item) fmt.Printf("%v\n", item)
if l.state == nil { if l.state == nil {
break break
} }
} }
} }
@ -46,14 +46,14 @@ func sendProbe(c *dns.Client, addr string, f *fingerprint, q dns.Question) *fing
m := f.toProbe(q) m := f.toProbe(q)
r, err := c.Exchange(m, addr) r, err := c.Exchange(m, addr)
if err != nil { if err != nil {
return errorToFingerprint(err) return errorToFingerprint(err)
} }
return msgToFingerprint(r) return msgToFingerprint(r)
} }
// This leads to strings like: "QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,1,DO,4096" // This leads to strings like: "QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,1,DO,4096"
type fingerprint struct { type fingerprint struct {
Error string Error os.Error
Opcode int Opcode int
Rcode int Rcode int
Response bool Response bool
@ -159,10 +159,21 @@ func (f *fingerprint) setString(str string) {
return return
} }
func (f *fingerprint) ok() bool {
return f.Error == nil
}
func (f *fingerprint) error() string {
if f.Error == nil {
panic("error is nil")
}
return f.Error.String()
}
func errorToFingerprint(e os.Error) *fingerprint { func errorToFingerprint(e os.Error) *fingerprint {
f := new(fingerprint) f := new(fingerprint)
f.Error = e.String() f.Error = e
return f return f
} }
func msgToFingerprint(m *dns.Msg) *fingerprint { func msgToFingerprint(m *dns.Msg) *fingerprint {

View File

@ -1,3 +1,7 @@
// We handle the checking as a lexing program.
// We use the lexer like Rob Pike lectures about in this
// clip: http://www.youtube.com/watch?v=HxaD_trXwRE
package main package main
import ( import (
@ -6,16 +10,13 @@ import (
type itemType int type itemType int
// We handle the checking as a lexing program.
// We use the lexer like Rob Pike lectures about in this
// clip: http://www.youtube.com/watch?v=HxaD_trXwRE
type item struct { type item struct {
typ itemType typ itemType
val string val string
} }
const ( const (
_ itemType = iota itemError itemType = iota
itemVender // software vendor itemVender // software vendor
itemSoftware // the name of the DNS server software itemSoftware // the name of the DNS server software
itemVersionMin // the minimum version of the software (empty if not determined) itemVersionMin // the minimum version of the software (empty if not determined)
@ -32,7 +33,6 @@ type lexer struct {
q dns.Question // question to ask. q dns.Question // question to ask.
items chan item // channel of scanned items. items chan item // channel of scanned items.
state stateFn // the next function to enter. state stateFn // the next function to enter.
error string // error text.
} }
func (l *lexer) probe() *fingerprint { func (l *lexer) probe() *fingerprint {
@ -51,39 +51,42 @@ func (l *lexer) setQuestion(name string, t uint16, c uint16) {
l.q = dns.Question{name, t, c} l.q = dns.Question{name, t, c}
} }
// Set the error
func (l *lexer) setError(s string) {
l.error = s
}
func (l *lexer) run() { func (l *lexer) run() {
go func() { go func() {
for l.state != nil { for l.state != nil {
l.state = l.state(l) l.state = l.state(l)
} }
close(l.items) close(l.items)
}() }()
} }
// "Lexer" functions // "Lexer" functions, prefixed with dns
// Check if the server responds // Check if the server responds
func lexAlive(l *lexer) stateFn { func dnsAlive(l *lexer) stateFn {
println("lexAlive") println("lexAlive")
l.setString("QUERY,NOERROR,qr,aa,tc,rd,ad,cd,z,1,0,0,0,do,0")
l.setQuestion(".", dns.TypeNS, dns.ClassINET)
//l.fp.SetString("QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,0,DO,0") f := l.probe()
//l.q = dns.Question{".", dns.TypeNS, dns.ClassINET}
return lexDoBitMirror 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. // Check if the server returns the DO-bit when set in the request.
func lexDoBitMirror(l *lexer) stateFn { func dnsDoBitMirror(l *lexer) stateFn {
println("lexDoBitMirror") println("lexDoBitMirror")
// The important part here is that the DO bit is on // The important part here is that the DO bit is on
l.setString("QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,0,DO,0") l.setString("QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,0,DO,0")
l.setQuestion(".", dns.TypeNS, dns.ClassINET) l.setQuestion(".", dns.TypeNS, dns.ClassINET)
if l.probe().Do {
f := l.probe()
if f.Do {
l.emit(&item{itemSoftware, NSD}) l.emit(&item{itemSoftware, NSD})
} }
l.emit(&item{itemSoftware, BIND}) l.emit(&item{itemSoftware, BIND})