From 1b96a4413ad63b2d2184f07f88acb7ff262e1a06 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Mon, 19 Sep 2011 15:16:05 +0200 Subject: [PATCH] added --- _examples/q/Makefile | 2 +- _examples/q/fp.go | 61 ++++++++++++++++++++++++++++++++++++++++++++ _examples/q/q.go | 52 ++++++++++++++++++++----------------- 3 files changed, 90 insertions(+), 25 deletions(-) create mode 100644 _examples/q/fp.go diff --git a/_examples/q/Makefile b/_examples/q/Makefile index f587d26c..25a8f65d 100644 --- a/_examples/q/Makefile +++ b/_examples/q/Makefile @@ -3,6 +3,6 @@ # license that can be found in the LICENSE file. include $(GOROOT)/src/Make.inc TARG=q -GOFILES=q.go +GOFILES=q.go fp.go DEPS=../../ include $(GOROOT)/src/Make.cmd diff --git a/_examples/q/fp.go b/_examples/q/fp.go new file mode 100644 index 00000000..819fab2e --- /dev/null +++ b/_examples/q/fp.go @@ -0,0 +1,61 @@ +// Package main provides ... +package main + +import ( + "dns" + "strconv" + "strings" +) + +// fingerPrint creates a (short) string representation of a dns message. +// If a bit is set we uppercase the name 'AD' otherwise it's lowercase 'ad'. +func msgToFingerPrint(m *dns.Msg) string { + if m == nil { + return "" + } + h := m.MsgHdr + + // Use the same order as in Perl's fpdns. + // But use more flags. + s := dns.Opcode_str[h.Opcode] + s += "," + dns.Rcode_str[h.Rcode] + s += valueOf(h.Response, ",qr") + s += valueOf(h.Authoritative, ",aa") + s += valueOf(h.Truncated, ",tc") + s += valueOf(h.RecursionDesired, ",rd") + s += valueOf(h.AuthenticatedData, ",ad") + s += valueOf(h.CheckingDisabled, ",ad") + s += valueOf(h.Zero, ",z") + + s += "," + strconv.Itoa(len(m.Question)) + s += "," + strconv.Itoa(len(m.Answer)) + s += "," + strconv.Itoa(len(m.Ns)) + s += "," + strconv.Itoa(len(m.Extra)) + + // EDNS0 + // V0,DO,4096 (all on) + // v0,do,0 (all off) + for _, r := range m.Extra { + if r.Header().Rrtype == dns.TypeOPT { + // version is always 0 - and I cannot set it anyway + s += valueOf(r.(*dns.RR_OPT).Do(), ",do") + s += "," + strconv.Itoa(int(r.(*dns.RR_OPT).UDPSize())) + return s + } + } + s += ",do,0" + return s +} + +// Create a dns message from a fingerprint string +func fingerPrintToProbe(fp string, q dns.Question) *dns.Msg { + + return nil +} + +func valueOf(x bool, w string) string { + if x { + return strings.ToUpper(w) + } + return strings.ToLower(w) +} diff --git a/_examples/q/q.go b/_examples/q/q.go index 33e26830..30385f68 100644 --- a/_examples/q/q.go +++ b/_examples/q/q.go @@ -12,22 +12,23 @@ import ( func q(w dns.RequestWriter, m *dns.Msg) { w.Send(m) r, err := w.Receive() - if err != nil { - fmt.Printf("%s\n", err.String()) - } + if err != nil { + fmt.Printf("%s\n", err.String()) + } w.Write(r) } func main() { - var dnssec *bool = flag.Bool("dnssec", false, "request DNSSEC records") - var query *bool = flag.Bool("question", false, "show question") - var short *bool = flag.Bool("short", false, "abbreviate long DNSKEY and RRSIG RRs") - var aa *bool = flag.Bool("aa", false, "set AA flag in query") - var ad *bool = flag.Bool("ad", false, "set AD flag in query") - var cd *bool = flag.Bool("cd", false, "set CD flag in query") - var rd *bool = flag.Bool("rd", true, "unset RD flag in query") - var tcp *bool = flag.Bool("tcp", false, "TCP mode") - var nsid *bool = flag.Bool("nsid", false, "ask for NSID") + dnssec := flag.Bool("dnssec", false, "request DNSSEC records") + query := flag.Bool("question", false, "show question") + short := flag.Bool("short", false, "abbreviate long DNSKEY and RRSIG RRs") + aa := flag.Bool("aa", false, "set AA flag in query") + ad := flag.Bool("ad", false, "set AD flag in query") + cd := flag.Bool("cd", false, "set CD flag in query") + rd := flag.Bool("rd", true, "unset RD flag in query") + tcp := flag.Bool("tcp", false, "TCP mode") + nsid := flag.Bool("nsid", false, "ask for NSID") + fp := flag.Bool("fingerprint", false, "enable server detection") flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [@server(:port)] [qtype] [qclass] [name ...]\n", os.Args[0]) flag.PrintDefaults() @@ -89,10 +90,10 @@ Flags: if !strings.HasSuffix(nameserver, ":53") { nameserver += ":53" } - // ipv6 todo - // We use the async query handling, just to show how - // it is to be used. + // ipv6 todo + // We use the async query handling, just to show how + // it is to be used. dns.HandleQueryFunc(".", q) dns.ListenAndQuery(nil, nil) c := dns.NewClient() @@ -107,14 +108,14 @@ Flags: m.MsgHdr.RecursionDesired = *rd m.Question = make([]dns.Question, 1) if *dnssec || *nsid { - m.SetEdns0(dns.DefaultMsgSize, true) + m.SetEdns0(dns.DefaultMsgSize, true) } for _, v := range qname { m.Question[0] = dns.Question{v, qtype, qclass} m.Id = dns.Id() - if *query { - fmt.Printf("%s\n", m.String()) - } + if *query { + fmt.Printf("%s\n", m.String()) + } c.Do(m, nameserver) } @@ -124,14 +125,17 @@ forever: select { case r := <-dns.DefaultReplyChan: if r.Reply != nil { - if r.Reply.Rcode == dns.RcodeSuccess { - if r.Request.Id != r.Reply.Id { - fmt.Printf("Id mismatch\n") - } - } + if r.Reply.Rcode == dns.RcodeSuccess { + if r.Request.Id != r.Reply.Id { + fmt.Printf("Id mismatch\n") + } + } if *short { r.Reply = shortMsg(r.Reply) } + if *fp { + fmt.Printf("%s\n", msgToFingerPrint(r.Reply)) + } fmt.Printf("%v", r.Reply) } i++