dns/_examples/q/lex.go
2011-12-20 10:29:00 +01:00

92 lines
2.2 KiB
Go

// 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 (
"dns"
"fmt"
)
type itemType int
type item struct {
typ itemType
val string
}
const (
itemError itemType = iota
itemSoftware // the name of the DNS server software
itemVendor // vendor of the DNS software
itemVersionMajor // the major version of the software (empty if not determined)
itemVersionMinor // the minor version of the software (empty if not determined)
itemVersionPatch // the patch level of the software (empty if not determined)
)
var itemString = map[itemType]string{
itemError: "error",
itemSoftware: "software",
itemVendor: "vendor",
itemVersionMajor: "major",
itemVersionMinor: "minor",
itemVersionPatch: "patch",
}
// stateFn represents the state of the scanner as a function that returns the next state.
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.
q dns.Question // question to ask.
items chan item // channel of scanned items.
state stateFn // the next function to enter.
verbose bool // if true, the fingerprints are printed.
debugging bool // If true, print the function names.
}
func (l *lexer) probe() (*fingerprint, dns.Question) {
f, q := sendProbe(l.client, l.addr, l.fp, l.q)
if l.verbose {
fmt.Printf("QR : %s\t-", f)
fmt.Printf(" (%s)\n", q.String())
}
return f, q
}
func (l *lexer) emit(i *item) {
l.items <- *i
}
func (l *lexer) setString(s string) {
l.fp.setString(s)
if l.verbose {
fmt.Printf("Q : %s\t-", s)
}
}
func (l *lexer) setQuestion(name string, t uint16, c uint16) {
l.q = dns.Question{name, t, c}
if l.verbose {
fmt.Printf(" (%s)\n", l.q.String())
}
}
func (l *lexer) run() {
go func() {
for l.state != nil {
l.state = l.state(l)
}
close(l.items)
}()
}
func (l *lexer) debug(s string) {
if l.debugging {
fmt.Printf(" dns%s\n", s)
}
}