Starts to work

This commit is contained in:
Miek Gieben 2011-09-20 09:19:33 +02:00
parent b9960f42ed
commit 84c1eba6b7
2 changed files with 77 additions and 31 deletions

View File

@ -3,6 +3,8 @@ package main
import (
"dns"
"fmt"
"os"
"strconv"
"strings"
)
@ -18,26 +20,33 @@ const (
)
func startParse(addr string) {
l := new(lexer)
l.addr = addr
l.client = new(dns.Client)
l.fp = new(fingerprint)
l.items = make(chan item)
for l.state = lexDoBitMirror; l.state != nil; l.state = l.state(l) {
// l.state = l.state(l)
l := &lexer {
addr: addr,
client: dns.NewClient(),
fp: new(fingerprint),
items: make(chan item),
state: lexAlive,
}
l.run()
// Not completely sure about this code..
for {
item := <-l.items
fmt.Printf("%v\n", item)
if l.state == nil {
break
}
}
}
// SendProbe creates a packet and sends it to the nameserver.
// Connection errors are returned as:
// ...
// SendProbe creates a packet and sends it to the nameserver. It
// returns a fingerprint.
func sendProbe(c *dns.Client, addr string, f *fingerprint, q dns.Question) *fingerprint {
m := f.toProbe(q)
r, err := c.Exchange(m, addr)
if err != nil {
println(err.String())
// return "connection error"
return nil
return errorToFingerprint(err)
}
return msgToFingerprint(r)
}
@ -91,7 +100,7 @@ func (f *fingerprint) String() string {
}
// SetString set the string to fp.. todo
func (f *fingerprint) SetString(str string) {
func (f *fingerprint) setString(str string) {
for i, s := range strings.Split(str, ",") {
switch i {
case 0:
@ -150,6 +159,12 @@ func (f *fingerprint) SetString(str string) {
return
}
func errorToFingerprint(e os.Error) *fingerprint {
f := new(fingerprint)
f.Error = e.String()
return f
}
func msgToFingerprint(m *dns.Msg) *fingerprint {
if m == nil {
return nil
@ -185,8 +200,7 @@ func msgToFingerprint(m *dns.Msg) *fingerprint {
}
// Create a dns message from a fingerprint string and
// a DNS question. The order of a string is always the
// same.
// a DNS question. The order of a string is always the same.
// QUERY,NOERROR,qr,aa,tc,RD,ad,ad,z,1,0,0,1,DO,4096
func (f *fingerprint) toProbe(q dns.Question) *dns.Msg {
m := new(dns.Msg)

View File

@ -15,11 +15,11 @@ type item struct {
}
const (
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)
itemVersionMax // the maximum version of the software (empty if not determined)
_ itemType = iota
itemVender // software vendor
itemSoftware // the name of the DNS server software
itemVersionMin // the minimum version of the software (empty if not determined)
itemVersionMax // the maximum version of the software (empty if not determined)
)
// stateFn represents the state of the scanner as a function that returns the next state.
@ -28,10 +28,11 @@ type stateFn func(*lexer) stateFn
type lexer struct {
client *dns.Client // client used.
addr string // addr of the server being scanned.
fp *fingerprint // fingerprint to test.
fp *fingerprint // fingerprint to test.
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 {
@ -39,21 +40,52 @@ func (l *lexer) probe() *fingerprint {
}
func (l *lexer) emit(i *item) {
l.items <- *i
l.items <- *i
}
func (l *lexer) setString(s string) {
l.fp.setString(s)
}
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)
}
close(l.items)
}()
}
// "Lexer" functions
// Check if the server responds
func lexAlive(l *lexer) stateFn {
println("lexAlive")
//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
}
// Check if the server returns the DO-bit when set in the request.
func lexDoBitMirror(l *lexer) stateFn {
println("lexDoBitMirror")
// The important part here is that the DO bit is on
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}
if l.probe().Do {
println(NSD)
// l.emit(&item{itemSoftware, NSD})
}
//l.emit(&item{itemSoftware, BIND})
println(BIND)
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 {
l.emit(&item{itemSoftware, NSD})
}
l.emit(&item{itemSoftware, BIND})
return nil
}