func handleQueryCHAOS(w dns.ResponseWriter, req *dns.Msg) { m := new(dns.Msg) qname := strings.ToLower(req.Question[0].Name) qtype := req.Question[0].Qtype qclass := req.Question[0].Qclass m.Extra = make([]dns.RR, 1) m.Extra[0] = spamCH if qclass != dns.ClassCHAOS { m.SetRcode(req, dns.RcodeServerFailure) send(w, m) return } if (qname == "version.bind." || qname == "id.server.") && qtype == dns.TypeTXT { m.SetReply(req) m.Answer = make([]dns.RR, 1) m.Answer[0] = &dns.RR_TXT{Hdr: dns.RR_Header{Name: qname, Rrtype: qtype, Class: qclass}, Txt: "NS 0.0.1"} send(w, m) return } if (qname == "authors.bind." || qname == "authors.server.") && qtype == dns.TypeTXT { m.SetReply(req) m.Answer = make([]dns.RR, 1) m.Answer[0] = &dns.RR_TXT{Hdr: dns.RR_Header{Name: qname, Rrtype: qtype, Class: qclass}, Txt: "Miek Gieben"} send(w, m) return } m.SetRcode(req, dns.RcodeServerFailure) send(w, m) return }
func handleReflect(w dns.ResponseWriter, r *dns.Msg) { var ( v4 bool rr dns.RR str string a net.IP ) // TC must be done here m := new(dns.Msg) m.SetReply(r) m.Compress = *compress if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (udp)" a = ip.IP v4 = a.To4() != nil } if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)" a = ip.IP v4 = a.To4() != nil } if v4 { rr = new(dns.RR_A) rr.(*dns.RR_A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.RR_A).A = a.To4() } else { rr = new(dns.RR_AAAA) rr.(*dns.RR_AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.RR_AAAA).AAAA = a } t := new(dns.RR_TXT) t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} t.Txt = []string{str} switch r.Question[0].Qtype { case dns.TypeTXT: m.Answer = append(m.Answer, t) m.Extra = append(m.Extra, rr) default: fallthrough case dns.TypeAAAA, dns.TypeA: m.Answer = append(m.Answer, rr) m.Extra = append(m.Extra, t) } if r.IsTsig() { if w.TsigStatus() == nil { m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.RR_TSIG).Hdr.Name, dns.HmacMD5, 300, r.MsgHdr.Id, time.Now().Unix()) } else { println("Status", w.TsigStatus().Error()) } } if *printf { fmt.Printf("%v\n", m.String()) } w.Write(m) }
func handleQuery(w dns.ResponseWriter, req *dns.Msg) { var dnssec bool m := new(dns.Msg) if req.Question[0].Qclass != dns.ClassINET { m.SetRcode(req, dns.RcodeServerFailure) send(w, m) return } m.SetReply(req) m.Ns = ns m.Extra = make([]dns.RR, 1) m.Extra[0] = spamIN // Check DNSSEC OK for _, v := range req.Extra { if o, ok := v.(*dns.RR_OPT); ok { if dnssec = o.Do(); dnssec { m.Extra = append(m.Extra, o) m.Ns = nsDNSSEC break } } } //m.Answer = make([]dns.RR, 0) s, _ := zone.LookupQuestion(req.Question[0]) if s == nil { // Authority section should only contain the SOA record for NXDOMAIN m.Ns = m.Ns[:1] m.Ns[0] = soa m.MsgHdr.Rcode = dns.RcodeNameError send(w, m) // Lookup the previous name in the Nxt list for this zone // and insert the nsec/nsec3 from that. Also give the nsec // that proofs there is no wildcard return } // TODO CNAME //cname: switch req.Question[0].Qtype { case dns.TypeRRSIG: m.Answer = s.RRsigs case dns.TypeNSEC, dns.TypeNSEC3: m.Answer = []dns.RR{s.Nxt} default: m.Answer = s.RRs } if dnssec && req.Question[0].Qtype != dns.TypeRRSIG && len(s.RRsigs) > 0 { for _, r := range s.RRsigs { m.Answer = append(m.Answer, r) } } if *debug { println(m.Question[0].String()) } send(w, m) }
func respondWithFallback(raw []uint8, clientMsg *dns.Msg, clientQuestion dns.Question, proxy *net.UDPAddr) { LOG.Println("fallback:", clientQuestion, proxy) conn, err := net.Dial("udp", proxy.String()) if err != nil { LOG.Fatalln(err) } conn.Write(raw) buffer := make([]byte, 1<<15) size, err := conn.Read(buffer) if err != nil { LOG.Fatalln(err, proxy) } msg := &dns.Msg{} msg.Unpack(buffer[0:size]) LOG.Println(msg) for _, answer := range msg.Answer { clientMsg.Answer = append(clientMsg.Answer, answer) } clientMsg.Rcode = msg.Rcode clientMsg.Response = msg.Response clientMsg.Authoritative = msg.Authoritative clientMsg.Recursion_desired = msg.Recursion_desired clientMsg.Recursion_available = msg.Recursion_available }
func handleReflect(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg) m.SetReply(r) m.Extra = make([]dns.RR, 1) m.Answer = make([]dns.RR, 1) var ( v4 bool rr dns.RR str string a net.IP ) if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (udp)" a = ip.IP v4 = a.To4() != nil } if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)" a = ip.IP v4 = a.To4() != nil } if v4 { rr = new(dns.RR_A) rr.(*dns.RR_A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.RR_A).A = a } else { rr = new(dns.RR_AAAA) rr.(*dns.RR_AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.RR_AAAA).AAAA = a } t := new(dns.RR_TXT) t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} t.Txt = str m.Extra[0] = t m.Answer[0] = rr b, ok := m.Pack() if !ok { return } w.Write(b) }
func reply(c *dns.Conn, in *dns.Msg) []byte { m := new(dns.Msg) m.SetReply(in) m.Question = make([]dns.Question, 1) m.Answer = make([]dns.RR, 1) m.Extra = make([]dns.RR, 1) // Copy the question. m.Question[0] = in.Question[0] // Some foo to check if we are called through ip6 or ip4. // We add the correct reply RR. var ad net.IP if c.UDP != nil { ad = c.Addr.(*net.UDPAddr).IP } else { ad = c.Addr.(*net.TCPAddr).IP } if ad.To4() != nil { r := new(dns.RR_A) r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} r.A = ad m.Answer[0] = r } else { r := new(dns.RR_AAAA) r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} r.AAAA = ad m.Answer[0] = r } t := new(dns.RR_TXT) t.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} if c.TCP != nil { t.Txt = "Port: " + strconv.Itoa(c.Port) + " (tcp)" } else { t.Txt = "Port: " + strconv.Itoa(c.Port) + " (udp)" } m.Extra[0] = t b, _ := m.Pack() return b }
func answerAAAA(msg *dns.Msg, question dns.Question, name []string, value NMCValue) { var parsedIp net.IP // len == 1 means root domain: check "ip" and "map"."" if len(name) == 1 { vips := value.Ip6 if len(vips) == 0 { // can't answer, make an error here. return } else { parsedIp = net.ParseIP(vips[0]) } } ip := parsedIp.To16() if ip == nil { return } LOG.Println("AAAA", name, "=>", ip) rraaaa := &dns.RR_AAAA{} copy(ip, rraaaa.AAAA[:]) rrh := &dns.RR_Header{ Name: question.Name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 60, Rdlength: 100, } rraaaa.Hdr = *rrh msg.Rcode = dns.RcodeSuccess msg.Answer = append(msg.Answer, rraaaa) msg.Response = true msg.Authoritative = true msg.Recursion_desired = true msg.Recursion_available = true }
func sign(m *dns.Msg) *dns.Msg { sg := new(dns.RR_RRSIG) sg.Hdr = dns.RR_Header{"www.example.org.", dns.TypeRRSIG, dns.ClassINET, 14400, 0} sg.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" sg.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" sg.KeyTag = pubkey.KeyTag() // Get the keyfrom the Key sg.SignerName = pubkey.Hdr.Name sg.Algorithm = dns.AlgRSASHA256 if len(m.Answer) > 0 { // sign the first record an := m.Answer[0] sg.TypeCovered = an.Header().Rrtype sg.Labels = dns.LabelCount(an.Header().Name) sg.OrigTtl = an.Header().Ttl switch p := privkey.(type) { case *rsa.PrivateKey: sg.Sign(p, []dns.RR{an}) } } m.Answer = append(m.Answer, sg) return m }
func handleReflect(w dns.ResponseWriter, r *dns.Msg) { var ( v4 bool rr dns.RR str string a net.IP ) m := new(dns.Msg) m.SetReply(r) if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (udp)" a = ip.IP v4 = a.To4() != nil } if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)" a = ip.IP v4 = a.To4() != nil } if v4 { rr = new(dns.RR_A) rr.(*dns.RR_A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.RR_A).A = a.To4() } else { rr = new(dns.RR_AAAA) rr.(*dns.RR_AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.RR_AAAA).AAAA = a } t := new(dns.RR_TXT) t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} t.Txt = str switch r.Question[0].Qtype { case dns.TypeTXT: m.Answer = append(m.Answer, t) m.Extra = append(m.Extra, rr) default: fallthrough case dns.TypeAAAA, dns.TypeA: m.Answer = append(m.Answer, rr) m.Extra = append(m.Extra, t) } /* nsec3 := new(dns.RR_NSEC3) nsec3.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeNSEC3, Class: dns.ClassINET, Ttl: 0} nsec3.Hash = dns.SHA1 nsec3.Flags = 0 nsec3.Iterations = 1 nsec3.Salt = "AABB" nsec3.SaltLength = uint8(len(nsec3.Salt)/2) nsec3.NextDomain = "miek.nl." nsec3.TypeBitMap = []uint16{dns.TypeA, dns.TypeNS, dns.TypeSOA, dns.TypeTXT, dns.TypeRRSIG, 4000, 4001, 5949} nsec3.HashNames("miek.nl.") m.Extra = append(m.Extra, nsec3) */ b, ok := m.Pack() if *printf { fmt.Printf("%v\n", m.String()) } if !ok { log.Print("Packing failed") m.SetRcode(r, dns.RcodeServerFailure) m.Extra = nil m.Answer = nil b, _ = m.Pack() } w.Write(b) }
func answerA(msg *dns.Msg, question dns.Question, name []string, value NMCValue) { var parsedIp net.IP // len == 1 means root domain: check "ip" and "map"."" if len(name) == 1 { vips := value.Ip // this is legacy support if len(vips) == 0 { vmap := value.Map if vmap == nil { return } vmip, ok := value.Map[""] if !ok && vmip == "" { // can't answer, make an error here. return } switch vmip.(type) { case nil: return case map[string]interface{}: nsAvailable := vmip.(map[string]interface{})["ns"] switch nsAvailable.(type) { case []interface{}: ns := nsAvailable.([]interface{})[0] switch ns.(type) { case string: h := dns.MsgHdr{ Id: uint16(rand.Int()) ^ uint16(time.Nanoseconds()), Recursion_desired: true, } q := &dns.Question{ Name: question.Name, Qtype: dns.TypeA, Qclass: dns.ClassINET, } m := &dns.Msg{} m.MsgHdr = h m.Question = append(m.Question, *q) LOG.Println(m) out, ok := m.Pack() if !ok { LOG.Fatalln("Failed to Pack:", msg) } nsaddr := ns.(string) + ":53" conn, err := net.Dial("udp", nsaddr) if err != nil { LOG.Fatalf("net.DialUDP(\"udp\", nil, %v) => %v", nsaddr, err) } LOG.Println("out:", out) n, err := conn.Write(out) if err != nil { LOG.Fatalln(err) } LOG.Println("wrote:", n) conn.SetReadTimeout(10e9) defer conn.Close() b := make([]byte, 1<<15) s, err := conn.Read(b) if err != nil { LOG.Fatalln(err, nsaddr) } err = conn.Close() if err != nil { LOG.Fatalln(err) } a := &dns.Msg{} a.Unpack(b[0:s]) LOG.Println("a:", a) msg.Answer = append(msg.Answer, a.Answer[0]) return default: LOG.Printf("can't find the type of: %#v", ns) } default: LOG.Printf("can't find the type of: %#v", nsAvailable) } case string: parsedIp = net.ParseIP(vmip.(string)) default: LOG.Printf("can't find the type of: %#v", vmip) } } else { parsedIp = net.ParseIP(vips[0]) } } ip := parsedIp.To4() if ip == nil { return } LOG.Println("A", name, "=>", ip) var a uint32 rra := &dns.RR_A{} rra.A = (a | uint32(ip[0])<<24 | uint32(ip[1])<<16 | uint32(ip[2])<<8 | uint32(ip[3])) rrh := &dns.RR_Header{ Name: question.Name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 60, Rdlength: 100, } rra.Hdr = *rrh msg.Rcode = dns.RcodeSuccess msg.Answer = append(msg.Answer, rra) msg.Response = true msg.Authoritative = true msg.Recursion_desired = true msg.Recursion_available = true }