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) {
l := &lexer {
addr: addr,
client: dns.NewClient(),
fp: new(fingerprint),
items: make(chan item),
state: lexAlive,
}
l := &lexer{
addr: addr,
client: dns.NewClient(),
fp: new(fingerprint),
items: make(chan item),
state: dnsAlive,
}
l.run()
l.run()
// Not completely sure about this code..
// Not completely sure about this code..
for {
item := <-l.items
fmt.Printf("%v\n", item)
if l.state == nil {
break
if l.state == nil {
break
}
}
}
@ -46,14 +46,14 @@ func sendProbe(c *dns.Client, addr string, f *fingerprint, q dns.Question) *fing
m := f.toProbe(q)
r, err := c.Exchange(m, addr)
if err != nil {
return errorToFingerprint(err)
return errorToFingerprint(err)
}
return msgToFingerprint(r)
}
// This leads to strings like: "QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,1,DO,4096"
type fingerprint struct {
Error string
Error os.Error
Opcode int
Rcode int
Response bool
@ -159,10 +159,21 @@ func (f *fingerprint) setString(str string) {
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 {
f := new(fingerprint)
f.Error = e.String()
return f
f := new(fingerprint)
f.Error = e
return f
}
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
import (
@ -6,16 +10,13 @@ import (
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 {
typ itemType
val string
}
const (
_ itemType = iota
itemError itemType = iota
itemVender // software vendor
itemSoftware // the name of the DNS server software
itemVersionMin // the minimum version of the software (empty if not determined)
@ -32,7 +33,6 @@ type lexer struct {
q dns.Question // question to ask.
items chan item // channel of scanned items.
state stateFn // the next function to enter.
error string // error text.
}
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}
}
// Set the error
func (l *lexer) setError(s string) {
l.error = s
}
func (l *lexer) run() {
go func() {
for l.state != nil {
l.state = l.state(l)
l.state = l.state(l)
}
close(l.items)
}()
}
// "Lexer" functions
// "Lexer" functions, prefixed with dns
// Check if the server responds
func lexAlive(l *lexer) stateFn {
func dnsAlive(l *lexer) stateFn {
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")
//l.q = dns.Question{".", dns.TypeNS, dns.ClassINET}
return lexDoBitMirror
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 lexDoBitMirror(l *lexer) stateFn {
func dnsDoBitMirror(l *lexer) stateFn {
println("lexDoBitMirror")
// 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.setQuestion(".", dns.TypeNS, dns.ClassINET)
if l.probe().Do {
f := l.probe()
if f.Do {
l.emit(&item{itemSoftware, NSD})
}
l.emit(&item{itemSoftware, BIND})