Beispiel #1
0
func main() {
	conf, err := dns.ClientConfigFromFile("/etc/resolv.conf")
	if len(os.Args) != 2 || err != nil {
		fmt.Printf("%s DOMAIN\n", os.Args[0])
		os.Exit(1)
	}
	m := new(dns.Msg)
	m.SetQuestion(dns.Fqdn(os.Args[1]), dns.TypeDNSKEY)
	m.SetEdns0(2048, true)

	c := new(dns.Client)
	r, _ := c.Exchange(m, conf.Servers[0]+":"+conf.Port)
	if r == nil {
		fmt.Printf("*** no answer received for %s\n", os.Args[1])
		os.Exit(1)
	}

	if r.Rcode != dns.RcodeSuccess {
		fmt.Printf(" *** invalid answer name %s after DNSKEY query for %s\n", os.Args[1], os.Args[1])
		os.Exit(1)
	}
	for _, k := range r.Answer {
		if key, ok := k.(*dns.RR_DNSKEY); ok {
			key.Hdr.Ttl = 0
			for _, alg := range []int{dns.SHA1, dns.SHA256, dns.SHA384} {
				ds := key.ToDS(alg)
				fmt.Printf("%v; %d\n", ds, key.Flags)
			}
		}
	}
}
Beispiel #2
0
func main() {
	c, err := dns.ClientConfigFromFile("/etc/resolv.conf")
	if len(os.Args) != 2 || err != nil {
		fmt.Printf("%s DOMAIN\n", os.Args[0])
		os.Exit(1)
	}
	m := new(dns.Msg)
	m.MsgHdr.RecursionDesired = true //only set this bit
	m.Question = make([]dns.Question, 1)
	m.Question[0] = dns.Question{os.Args[1], dns.TypeDNSKEY, dns.ClassINET}

	d := new(dns.Conn)
	d.RemoteAddr = c.Servers[0]
	in, err := dns.SimpleQuery("udp", d, m)
	if in != nil {
		if in.Rcode != dns.RcodeSuccess {
			fmt.Printf(" *** invalid answer name %s after DNSKEY query for %s\n", os.Args[1], os.Args[1])
			os.Exit(1)
		}
		// Stuff must be in the answer section
		for _, k := range in.Answer {
			// Foreach key would need to provide a DS records, both sha1 and sha256
			if key, ok := k.(*dns.RR_DNSKEY); ok {
				ds := key.ToDS(dns.HashSHA1)
				ds.Hdr.Ttl = 0
				fmt.Printf("%v\n", ds)
				ds = key.ToDS(dns.HashSHA256)
				ds.Hdr.Ttl = 0
				fmt.Printf("%v\n", ds)
			}
		}
	} else {
		fmt.Printf("*** error: %s\n", err.String())
	}
}
Beispiel #3
0
func main() {
	if len(os.Args) != 2 {
		fmt.Printf("%s NAMESERVER\n", os.Args[0])
		os.Exit(1)
	}
	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")

	m := new(dns.Msg)
	m.Question = make([]dns.Question, 1)
	c := dns.NewClient()

	addr := addresses(conf, c, os.Args[1])
	if len(addr) == 0 {
		fmt.Printf("No address found for %s\n", os.Args[1])
		os.Exit(1)
	}
	for _, a := range addr {
		m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS}
		in := c.Exchange(m, a)
		if in != nil && in.Answer != nil {
			fmt.Printf("%v\n", in.Answer[0])
		}
		m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS}
		in = c.Exchange(m, a)
		if in != nil && in.Answer != nil {
			fmt.Printf("%v\n", in.Answer[0])
		}
	}
}
Beispiel #4
0
func main() {
	if len(os.Args) != 2 {
		fmt.Printf("%s DOMAIN\n", os.Args[0])
		os.Exit(1)
	}

	// Error checking
	config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	c := dns.NewClient()

	m := new(dns.Msg)
	m.SetQuestion(os.Args[1], dns.TypeMX)
	m.MsgHdr.RecursionDesired = true

	// Simple sync query, nothing fancy
	r := c.Exchange(m, config.Servers[0])

	if r == nil {
		os.Exit(1)
	}

	if r.Rcode != dns.RcodeSuccess {
		fmt.Printf(" *** invalid answer name %s after MX query for %s\n", os.Args[1], os.Args[1])
		os.Exit(1)
	}
	// Stuff must be in the answer section
	for _, a := range r.Answer {
		fmt.Printf("%v\n", a)
	}
}
Beispiel #5
0
func main() {
	c, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	if len(os.Args) != 2 {
		fmt.Printf("%s DOMAIN\n", os.Args[0])
		os.Exit(1)
	}

	m := new(dns.Msg)
	m.Question = make([]dns.Question, 1)
	d := new(dns.Conn)
	d.RemoteAddr = c.Servers[0]
	for _, a := range addresses(d, os.Args[0]) {
		d.RemoteAddr = a
		if err := d.Dial("udp"); err != nil {
			fmt.Printf("%v\n", err)
			os.Exit(1)
		}

		m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS}
		in, _ := dns.SimpleQuery("udp", d, m)
		if in != nil && in.Answer != nil {
			fmt.Printf("%v\n", in.Answer[0])
		}
		m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS}
		in, _ = dns.SimpleQuery("udp", d, m)
		if in != nil && in.Answer != nil {
			fmt.Printf("%v\n", in.Answer[0])
		}
	}
}
Beispiel #6
0
func main() {
	port := flag.Int("port", 53, "port number to use")
	report := flag.Bool("report", false, "show fingerprint for (yet) unknown server")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS...] [@server]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	flag.Parse()

	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			break
		}
	}
	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)
	c := new(dns.Client)
	prints, _ := fingerPrintFromFile("data/q")
	results := make([]*fingerprint, 0)
	if *report {
		fmt.Printf("# Fingerprint of <Nameserver> <version>\n# Supplied by <Name> on <Date>\n#\n")
	}
	for _, f := range prints {
		f1 := probe(c, nameserver, f)
		results = append(results, f1)
		if *report {
			fmt.Printf("#%s\n%s\n", f.String(), f1.String())
		}
	}
	if *report {
		return
	}

	// For now, just list them:
	files := []string{"Atlas", "Bind8", "Bind9", "MaraDNS", "Microsoft", "Nsd3", "PowerDNS"}
	fmt.Printf("%s\t%s\t%s\t\t\t\t\t\t\t\t%s\n", "Server type", "Diffs", "Fingerprint", "Recevied")
	for _, file := range files {
		diff := 0
		prints, _ := fingerPrintFromFile("data/" + file)
		for i, f := range prints {
			d := f.compare(results[i])
			diff += d
			fmt.Printf("%s\t%d %s %s\n", file, d, f.String(), results[i].String())
		}
		fmt.Printf("\t\t=\nDifferences:\t%d\n\n", diff)
	}
}
Beispiel #7
0
func main() {
	conf, err := dns.ClientConfigFromFile("/etc/resolv.conf")
	if len(os.Args) != 2 || err != nil {
		fmt.Printf("%s DOMAIN\n", os.Args[0])
		os.Exit(1)
	}
	m := new(dns.Msg)
	m.SetQuestion(os.Args[1], dns.TypeDNSKEY)

	// Set EDNS0's Do bit
	e := new(dns.RR_OPT)
	e.Hdr.Name = "."
	e.Hdr.Rrtype = dns.TypeOPT
	e.SetUDPSize(2048)
	e.SetDo()
	m.Extra = append(m.Extra, e)

	c := dns.NewClient()
	r := c.Exchange(m, conf.Servers[0])
	if r == nil {
		fmt.Printf("*** no answer received for %s\n", os.Args[1])
		os.Exit(1)
	}

	if r.Rcode != dns.RcodeSuccess {
		fmt.Printf(" *** invalid answer name %s after DNSKEY query for %s\n", os.Args[1], os.Args[1])
		os.Exit(1)
	}
	// Stuff must be in the answer section, check len(r.Answer)
	for _, k := range r.Answer {
		// Foreach key would need to provide a DS records, both sha1 and sha256
		if key, ok := k.(*dns.RR_DNSKEY); ok {
			key.Hdr.Ttl = 0
			ds := key.ToDS(dns.SHA1)
			fmt.Printf("%v\n", ds)
			ds = key.ToDS(dns.SHA256)
			fmt.Printf("%v\n", ds)
			ds = key.ToDS(dns.SHA384)
			fmt.Printf("%v\n", ds)
		}
	}
}
Beispiel #8
0
func main() {
	if len(os.Args) != 2 {
		fmt.Printf("%s DOMAIN\n", os.Args[0])
		os.Exit(1)
	}
	d := new(dns.Conn)
	c, err := dns.ClientConfigFromFile("/etc/resolv.conf")
	// Errorchecking
	d.RemoteAddr = c.Servers[0]

	m := new(dns.Msg)
	m.Id = dns.Id()
	m.MsgHdr.RecursionDesired = true
	m.Question = make([]dns.Question, 1)
	m.Question[0] = dns.Question{os.Args[1], dns.TypeMX, dns.ClassINET}

	err = d.Dial("udp")
	if err != nil {
		fmt.Printf("*** error: %s\n", err.String())
		os.Exit(1)
	}

	in, err := dns.SimpleQuery("udp", d, m)
	if in != nil {
		if in.Rcode != dns.RcodeSuccess {
			fmt.Printf(" *** invalid answer name %s after MX query for %s\n", os.Args[1], os.Args[1])
			os.Exit(1)
		}
		// Stuff must be in the answer section
		for _, a := range in.Answer {
			fmt.Printf("%v\n", a)
		}
	} else {
		fmt.Printf("*** error: %s\n", err.String())
	}
}
Beispiel #9
0
Datei: q.go Projekt: wallrat/dns
func main() {
	dnssec := flag.Bool("dnssec", false, "request DNSSEC records")
	query := flag.Bool("question", false, "show question")
	short := flag.Bool("short", false, "abbreviate long DNSSEC records")
	check := flag.Bool("check", false, "check internal DNSSEC consistency")
	six := flag.Bool("6", false, "use IPv6 only")
	four := flag.Bool("4", false, "use IPv4 only")
	anchor := flag.String("anchor", "", "use the DNSKEY in this file for interal DNSSEC consistency")
	tsig := flag.String("tsig", "", "request tsig with key: [hmac:]name:key")
	port := flag.Int("port", 53, "port number to use")
	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, "set RD flag in query")
	fallback := flag.Bool("fallback", false, "fallback to 4096 bytes bufsize and after that TCP")
	tcp := flag.Bool("tcp", false, "TCP mode")
	nsid := flag.Bool("nsid", false, "set edns nsid option")
	client := flag.String("client", "", "set edns client-subnet option")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	qtype := uint16(0)
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()
	if *anchor != "" {
		f, err := os.Open(*anchor)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failure to open %s: %s\n", *anchor, err.Error())
		}
		r, err := dns.ReadRR(f, *anchor)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failure to read an RR from %s: %s\n", *anchor, err.Error())
		}
		if k, ok := r.(*dns.RR_DNSKEY); !ok {
			fmt.Fprintf(os.Stderr, "No DNSKEY read from %s\n", *anchor)
		} else {
			dnskey = k
		}
	}

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		if k, ok := dns.Str_rr[strings.ToUpper(flag.Arg(i))]; ok {
			qtype = k
			switch qtype {
			case dns.TypeAXFR:
				fmt.Fprintf(os.Stderr, "AXFR not supported\n")
				return
			case dns.TypeIXFR:
				fmt.Fprintf(os.Stderr, "AXFR not supported\n")
				return
			}
			continue Flags
		}
		// If it looks like a class, it is a class
		if k, ok := dns.Str_class[strings.ToUpper(flag.Arg(i))]; ok {
			qclass = k
			continue Flags
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				switch qtype {
				case dns.TypeAXFR:
					fmt.Fprintf(os.Stderr, "AXFR not supported\n")
					return
				case dns.TypeIXFR:
					fmt.Fprintf(os.Stderr, "AXFR not supported\n")
					return
				}
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	if len(qname) == 0 {
		qname = make([]string, 1)
		qname[0] = "."
		qtype = dns.TypeNS
	}
	if qtype == 0 {
		qtype = dns.TypeA
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)

	// We use the async query handling, just to show how it is to be used.
	c := new(dns.Client)
	if *tcp {
		c.Net = "tcp"
		if *four {
			c.Net = "tcp4"
		}
		if *six {
			c.Net = "tcp6"
		}
	} else {
		c.Net = "udp"
		if *four {
			c.Net = "udp4"
		}
		if *six {
			c.Net = "udp6"
		}
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)

	if *dnssec || *nsid || *client != "" {
		o := new(dns.RR_OPT)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		if *dnssec {
			o.SetDo()
			o.SetUDPSize(dns.DefaultMsgSize)
		}
		if *nsid {
			e := new(dns.EDNS0_NSID)
			e.Code = dns.EDNS0NSID
			o.Option = append(o.Option, e)
			// NSD will not return nsid when the udp message size is too small
			o.SetUDPSize(dns.DefaultMsgSize)
		}
		if *client != "" {
			e := new(dns.EDNS0_SUBNET)
			e.Code = dns.EDNS0SUBNET
			e.SourceScope = 0
			e.Address = net.ParseIP(*client)
			if e.Address == nil {
				fmt.Fprintf(os.Stderr, "Failure to parse IP address: %s\n", *client)
				return
			}
			e.Family = 1 // IP4
			e.SourceNetmask = net.IPv4len * 8
			if e.Address.To4() == nil {
				e.Family = 2 // IP6
				e.SourceNetmask = net.IPv6len * 8
			}
			o.Option = append(o.Option, e)
		}
		m.Extra = append(m.Extra, o)
	}

	for i, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		m.Id = dns.Id()
		if *query {
			fmt.Printf("%s", m.String())
			fmt.Printf("\n;; size: %d bytes\n\n", m.Len())
		}
		// Add tsig
		if *tsig != "" {
			if algo, name, secret, ok := tsigKeyParse(*tsig); ok {
				m.SetTsig(name, algo, 300, time.Now().Unix())
				c.TsigSecret = map[string]string{name: secret}
			} else {
				fmt.Fprintf(os.Stderr, "tsig key data error\n")
				return
			}
		}
		c.DoRtt(m, nameserver, nil, func(m, r *dns.Msg, rtt time.Duration, e error, data interface{}) {
			defer func() {
				if i == len(qname)-1 {
					os.Exit(0)
				}
			}()
		Redo:
			if r == nil {
				return
			}
			if r.Rcode != dns.RcodeSuccess {
				return
			}
			if r.Id != m.Id {
				fmt.Printf("Id mismatch\n")
				return
			}
			if r.MsgHdr.Truncated && *fallback {
				if c.Net != "tcp" {
					if !*dnssec {
						fmt.Printf(";; Truncated, trying %d bytes bufsize\n", dns.DefaultMsgSize)
						o := new(dns.RR_OPT)
						o.Hdr.Name = "."
						o.Hdr.Rrtype = dns.TypeOPT
						o.SetUDPSize(dns.DefaultMsgSize)
						m.Extra = append(m.Extra, o)
						r, rtt, e = c.ExchangeRtt(m, nameserver)
						*dnssec = true
						goto Redo
					} else {
						// First EDNS, then TCP
						fmt.Printf(";; Truncated, trying TCP\n")
						c.Net = "tcp"
						r, rtt, e = c.ExchangeRtt(m, nameserver)
						goto Redo
					}
				}
			}
			if r.MsgHdr.Truncated && !*fallback {
				fmt.Printf(";; Truncated\n")
			}
			if *check {
				sigCheck(r, nameserver, *tcp)
				nsecCheck(r)
				//dns.AssertDelegationSigner(r.Reply, nil)
			}
			if *short {
				r = shortMsg(r)
			}

			fmt.Printf("%v", r)
			fmt.Printf("\n;; query time: %.3d µs, server: %s(%s), size: %d bytes\n", rtt/1e3, nameserver, c.Net, r.Size)

		})
	}
	select {}

}
Beispiel #10
0
func main() {
	dnssec := flag.Bool("dnssec", false, "request DNSSEC records")
	query := flag.Bool("question", false, "show question")
	short := flag.Bool("short", false, "abbreviate long DNSSEC records")
	check := flag.Bool("check", false, "check internal DNSSEC consistency")
	anchor := flag.String("anchor", "", "use the DNSKEY in this file for checking consistency")
	port := flag.Int("port", 53, "port number to use")
	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")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	qtype := uint16(0)
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()
	if *anchor != "" {
		f, err := os.Open(*anchor)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failure to open %s: %s\n", *anchor, err.Error())
		}
		r, err := dns.ReadRR(f, *anchor)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failure to read an RR from %s: %s\n", *anchor, err.Error())
		}
		if k, ok := r.(*dns.RR_DNSKEY); !ok {
			fmt.Fprintf(os.Stderr, "No DNSKEY read from %s\n", *anchor)
		} else {
			dnskey = k
		}
	}

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		if k, ok := dns.Str_rr[strings.ToUpper(flag.Arg(i))]; ok {
			qtype = k
			continue Flags
		}
		// If it looks like a class, it is a class
		if k, ok := dns.Str_class[strings.ToUpper(flag.Arg(i))]; ok {
			qclass = k
			continue Flags
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	if len(qname) == 0 {
		qname = make([]string, 1)
		qname[0] = "."
		qtype = dns.TypeNS
	}
	if qtype == 0 {
		qtype = dns.TypeA
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)

	// 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()
	if *tcp {
		c.Net = "tcp"
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec || *nsid {
		o := new(dns.RR_OPT)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		if *dnssec {
			o.SetDo()
			o.SetUDPSize(dns.DefaultMsgSize)
		}
		if *nsid {
			o.SetNsid("")
		}
		m.Extra = append(m.Extra, o)
	}

	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		m.Id = dns.Id()
		if *query {
			fmt.Printf("%s\n", m.String())
		}
		c.Do(m, nameserver)
	}

	i := 0
forever:
	for {
		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 *check {
					sigCheck(r.Reply, nameserver, *tcp)
					nsecCheck(r.Reply)
				}
				if *short {
					r.Reply = shortMsg(r.Reply)
				}

				fmt.Printf("%v", r.Reply)
			}
			i++
			if i == len(qname) {
				break forever
			}
		}
	}
}
Beispiel #11
0
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, "abbriate 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")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server(:port)] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	// Need to think about it... Config
	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	qtype := uint16(0)
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		for k, v := range dns.Rr_str {
			if v == strings.ToUpper(flag.Arg(i)) {
				qtype = k
				continue Flags
			}
		}
		// If it looks like a class, it is a class
		for k, v := range dns.Class_str {
			if v == strings.ToUpper(flag.Arg(i)) {
				qclass = k
				continue Flags
			}
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	if len(qname) == 0 {
		qname = make([]string, 1)
		qname[0] = "."
		qtype = dns.TypeNS
	}
	if qtype == 0 {
		qtype = dns.TypeA
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	if !strings.HasSuffix(nameserver, ":53") {
		nameserver += ":53"
	}
	// 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()
	if *tcp {
		c.Net = "tcp"
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec || *nsid {
		opt := dns.NewRR(dns.TypeOPT).(*dns.RR_OPT)
		opt.Hdr.Rrtype = 0
		opt.SetDo()
		opt.SetVersion(0)
		opt.SetUDPSize(dns.DefaultMsgSize)
		if *nsid {
			opt.SetNsid("")
		}
		m.Extra = make([]dns.RR, 1)
		m.Extra[0] = opt
	}
	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		m.Id = dns.Id()
		if *query {
			fmt.Printf("%s\n", m.String())
		}
		c.Do(m, nameserver)
	}

	i := 0
forever:
	for {
		select {
		case r := <-dns.DefaultReplyChan:
			if r[1] != nil {
				if r[0].Id != r[1].Id {
					fmt.Printf("Id mismatch\n")
				}
				if *short {
					r[1] = shortMsg(r[1])
				}
				fmt.Printf("%v", r[1])
			}
			i++
			if i == len(qname) {
				break forever
			}
		}
	}
}
Beispiel #12
0
func main() {
	var dnssec *bool = flag.Bool("dnssec", false, "Request DNSSEC records")
	var short *bool = flag.Bool("short", false, "Abbriate 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 the NSID")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server(:port)] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	// Need to think about it... Config
	c, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + c.Servers[0]
	qtype := uint16(dns.TypeA)      // Default qtype
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		for k, v := range dns.Rr_str {
			if v == strings.ToUpper(flag.Arg(i)) {
				qtype = k
				continue Flags
			}
		}
		// If it looks like a class, it is a class
		for k, v := range dns.Class_str {
			if v == strings.ToUpper(flag.Arg(i)) {
				qclass = k
				continue Flags
			}
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	if !strings.HasSuffix(nameserver, ":53") {
		nameserver += ":53"
	}

	err := make(chan os.Error)
	if *tcp {
		go query("tcp", err)
	} else {
		go query("udp", err)
	}

	dns.InitQueryChannels()
	// Start the querier in a closure
	go func() {
		for _, v := range qname {
			d, m := newConnMsg(v, nameserver, c.Attempts, qtype, qclass, *aa, *ad, *cd, *rd, *dnssec, *nsid)
			dns.QueryRequest <- &dns.Query{Query: m, Conn: d}
		}
	}()

	i := 0
forever:
	for {
		select {
		case r := <-dns.QueryReply:
			if r.Reply != nil {
				if r.Query.Id != r.Reply.Id {
					fmt.Printf("Id mismatch\n")
				}
				if *short {
					r.Reply = shortMsg(r.Reply)
				}
				fmt.Printf("%v", r.Reply)
			} else {
				fmt.Printf("%v\n", r.Err.String())
			}
			i++
			if i == len(qname) {
				break forever
			}
		case e := <-err:
			fmt.Printf("%v", e.String())
			break forever
		}
	}
}
Beispiel #13
0
func main() {
	dnssec := flag.Bool("dnssec", false, "request DNSSEC records")
	query := flag.Bool("question", false, "show question")
	short := flag.Bool("short", false, "abbreviate long DNSSEC records")
	check := flag.Bool("check", false, "check internal DNSSEC consistency")
	six := flag.Bool("6", false, "use IPv6 only")
	four := flag.Bool("4", false, "use IPv4 only")
	anchor := flag.String("anchor", "", "use the DNSKEY in this file for interal DNSSEC consistency")
	tsig := flag.String("tsig", "", "request tsig with key: [hmac:]name:key")
	port := flag.Int("port", 53, "port number to use")
	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, "set RD flag in query")
	fallback := flag.Bool("fallback", false, "fallback to 4096 bytes bufsize and after that TCP")
	tcp := flag.Bool("tcp", false, "TCP mode")
	nsid := flag.Bool("nsid", false, "ask for NSID")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	qtype := uint16(0)
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()
	if *anchor != "" {
		f, err := os.Open(*anchor)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failure to open %s: %s\n", *anchor, err.Error())
		}
		r, err := dns.ReadRR(f, *anchor)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failure to read an RR from %s: %s\n", *anchor, err.Error())
		}
		if k, ok := r.(*dns.RR_DNSKEY); !ok {
			fmt.Fprintf(os.Stderr, "No DNSKEY read from %s\n", *anchor)
		} else {
			dnskey = k
		}
	}

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		if k, ok := dns.Str_rr[strings.ToUpper(flag.Arg(i))]; ok {
			qtype = k
			switch qtype {
			case dns.TypeAXFR:
				fmt.Fprintf(os.Stderr, "AXFR not supported\n")
				return
			case dns.TypeIXFR:
				fmt.Fprintf(os.Stderr, "AXFR not supported\n")
				return
			}
			continue Flags
		}
		// If it looks like a class, it is a class
		if k, ok := dns.Str_class[strings.ToUpper(flag.Arg(i))]; ok {
			qclass = k
			continue Flags
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				switch qtype {
				case dns.TypeAXFR:
					fmt.Fprintf(os.Stderr, "AXFR not supported\n")
					return
				case dns.TypeIXFR:
					fmt.Fprintf(os.Stderr, "AXFR not supported\n")
					return
				}
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	if len(qname) == 0 {
		qname = make([]string, 1)
		qname[0] = "."
		qtype = dns.TypeNS
	}
	if qtype == 0 {
		qtype = dns.TypeA
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)

	// We use the async query handling, just to show how it is to be used.
	dns.HandleQuery(".", q)
	dns.ListenAndQuery(nil)
	c := new(dns.Client)
	if *tcp {
		c.Net = "tcp"
		if *four {
			c.Net = "tcp4"
		}
		if *six {
			c.Net = "tcp6"
		}
	} else {
		c.Net = "udp"
		if *four {
			c.Net = "udp4"
		}
		if *six {
			c.Net = "udp6"
		}
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec || *nsid {
		o := new(dns.RR_OPT)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		if *dnssec {
			o.SetDo()
			o.SetUDPSize(dns.DefaultMsgSize)
		}
		if *nsid {
			o.SetNsid("")
		}
		m.Extra = append(m.Extra, o)
	}

	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		m.Id = dns.Id()
		if *query {
			fmt.Printf("%s\n", m.String())
		}
		// Add tsig
		if *tsig != "" {
			if algo, name, secret, ok := tsigKeyParse(*tsig); ok {
				m.SetTsig(name, algo, 300, time.Now().Unix())
				c.TsigSecret = map[string]string{name: secret}
			} else {
				fmt.Fprintf(os.Stderr, "tsig key data error\n")
				return
			}
		}
		c.Do(m, nameserver)
	}

	i := 0
forever:
	for {
		select {
		case r := <-c.Reply:
			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.MsgHdr.Truncated && *fallback {
					if c.Net != "tcp" {
						if !*dnssec {
							fmt.Printf(";; Truncated, trying %d bytes bufsize\n", dns.DefaultMsgSize)
							o := new(dns.RR_OPT)
							o.Hdr.Name = "."
							o.Hdr.Rrtype = dns.TypeOPT
							o.SetUDPSize(dns.DefaultMsgSize)
							m.Extra = append(m.Extra, o)
							*dnssec = true
							c.Do(m, nameserver)
							break
						} else {
							// First EDNS, then TCP
							fmt.Printf(";; Truncated, trying TCP\n")
							c.Net = "tcp"
							c.Do(m, nameserver)
							break
						}
					}
				}
				if r.Reply.MsgHdr.Truncated && !*fallback {
					fmt.Printf(";; Truncated\n")
				}
				if *check {
					sigCheck(r.Reply, nameserver, *tcp)
					nsecCheck(r.Reply)
				}
				if *short {
					r.Reply = shortMsg(r.Reply)
				}

				fmt.Printf("%v", r.Reply)
				fmt.Printf("\n;; query time: %.3d µs, server: %s(%s)\n", r.Rtt/1e3, r.RemoteAddr, r.RemoteAddr.Network())
				// Server maybe
			}
			i++
			if i == len(qname) {
				break forever
			}
		}
	}
}