It is working now
This commit is contained in:
parent
84c1eba6b7
commit
8e71248212
|
@ -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 {
|
||||
|
|
|
@ -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})
|
||||
|
|
Loading…
Reference in New Issue