Example #1
2
// LookupIP returns hostname from PTR record or error.
func LookupIP(ip, serverAddr string) ([]string, error) {
	names := []string{}
	m := &dns.Msg{}
	ipArpa, err := dns.ReverseAddr(ip)
	if err != nil {
		return names, err
	}
	m.SetQuestion(ipArpa, dns.TypePTR)
	in, err := dns.Exchange(m, serverAddr+":53")
	if err != nil {
		return names, err
	}
	if len(in.Answer) < 1 {
		return names, errors.New("no Answer")
	}

	for _, a := range in.Answer {
		if ptr, ok := a.(*dns.PTR); ok {
			if strings.Contains(ptr.Ptr, strings.Join(strings.Split(ip, "."), "-")) {
				continue
			}
			names = append(names, strings.TrimRight(ptr.Ptr, "."))
		}
	}

	if len(names) < 1 {
		return names, errors.New("no PTR")
	}

	return names, nil
}
Example #2
0
func (s *Spy) mutateContainerInCache(id string, status string) {

	container, err := s.docker.InspectContainer(id)
	if err != nil {
		log.Printf("Unable to inspect container %s, skipping", id)
		return
	}

	name := container.Config.Hostname + "." + container.Config.Domainname + "."

	var running = regexp.MustCompile("start|^Up.*$")
	var stopping = regexp.MustCompile("die")

	switch {
	case running.MatchString(status):
		log.Printf("Adding record for %v", name)
		arpa, err := dns.ReverseAddr(container.NetworkSettings.IPAddress)
		if err != nil {
			log.Printf("Unable to create ARPA address. Reverse DNS lookup will be unavailable for this container.")
		}
		s.dns.cache.Set(name, &Record{
			container.NetworkSettings.IPAddress,
			arpa,
			name,
		})
	case stopping.MatchString(status):
		log.Printf("Removing record for %v", name)
		s.dns.cache.Remove(name)
	}
}
Example #3
0
// handlePtr is used to handle "reverse" DNS queries
func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
	q := req.Question[0]
	defer func(s time.Time) {
		d.logger.Printf("[DEBUG] dns: request for %v (%v) from client %s (%s)",
			q, time.Now().Sub(s), resp.RemoteAddr().String(),
			resp.RemoteAddr().Network())
	}(time.Now())

	// Setup the message response
	m := new(dns.Msg)
	m.SetReply(req)
	m.Authoritative = true
	m.RecursionAvailable = (len(d.recursors) > 0)

	// Only add the SOA if requested
	if req.Question[0].Qtype == dns.TypeSOA {
		d.addSOA(d.domain, m)
	}

	datacenter := d.agent.config.Datacenter

	// Get the QName without the domain suffix
	qName := strings.ToLower(dns.Fqdn(req.Question[0].Name))

	args := structs.DCSpecificRequest{
		Datacenter: datacenter,
		QueryOptions: structs.QueryOptions{
			Token:      d.agent.config.ACLToken,
			AllowStale: d.config.AllowStale,
		},
	}
	var out structs.IndexedNodes

	// TODO: Replace ListNodes with an internal RPC that can do the filter
	// server side to avoid transferring the entire node list.
	if err := d.agent.RPC("Catalog.ListNodes", &args, &out); err == nil {
		for _, n := range out.Nodes {
			arpa, _ := dns.ReverseAddr(n.Address)
			if arpa == qName {
				ptr := &dns.PTR{
					Hdr: dns.RR_Header{Name: q.Name, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: 0},
					Ptr: fmt.Sprintf("%s.node.%s.%s", n.Node, datacenter, d.domain),
				}
				m.Answer = append(m.Answer, ptr)
				break
			}
		}
	}

	// nothing found locally, recurse
	if len(m.Answer) == 0 {
		d.handleRecurse(resp, req)
		return
	}

	// Write out the complete response
	if err := resp.WriteMsg(m); err != nil {
		d.logger.Printf("[WARN] dns: failed to respond: %v", err)
	}
}
Example #4
0
// NewHandler returns a Handler filled from name and ip.
func NewHandler(name, ip string) *Handler {
	reverse, _ := dns.ReverseAddr(ip)
	return &Handler{
		name:    name,
		ip:      net.ParseIP(ip),
		reverse: reverse,
	}
}
Example #5
0
// Handler for reverse DNS queries
func ptr(w http.ResponseWriter, r *http.Request) {
	server := r.URL.Query().Get(":server")
	ip := r.URL.Query().Get(":ip")

	if arpa, err := dns.ReverseAddr(ip); err == nil { // Valid IP address (IPv4 or IPv6)
		resolve(w, r, server, arpa, dns.TypePTR)
	} else {
		error(w, 400, 403, "Input string is not a valid IP address")
	}
}
Example #6
0
func (h *Hostsfile) FindReverse(name string) (host string, err error) {
	h.hostMutex.RLock()
	defer h.hostMutex.RUnlock()

	for _, hostname := range *h.hosts {
		if r, _ := dns.ReverseAddr(hostname.ip.String()); name == r {
			host = dns.Fqdn(hostname.domain)
			break
		}
	}
	return
}
Example #7
0
func (r *dnsResolver) findReverse(address string) (hosts []string) {
	r.hostMutex.RLock()
	defer r.hostMutex.RUnlock()

	address = strings.ToLower(dns.Fqdn(address))

	for _, entry := range r.hosts {
		if r, _ := dns.ReverseAddr(entry.Address.String()); address == r && len(entry.Names) > 0 {
			hosts = append(hosts, dns.Fqdn(entry.Names[0]))
		}
	}
	return
}
Example #8
0
// LookupAddr performs a reverse lookup for the given address, returning a
// list of names mapping to that address.
func (u *Unbound) LookupAddr(addr string) (name []string, err error) {
	reverse, err := dns.ReverseAddr(addr)
	if err != nil {
		return nil, err
	}
	r, err := u.Resolve(reverse, dns.TypePTR, dns.ClassINET)
	if err != nil {
		return nil, err
	}
	for _, rr := range r.Rr {
		name = append(name, rr.(*dns.PTR).Ptr)
	}
	return
}
Example #9
0
func Hostname(ctx *Context, ipaddr string, ext Extension) (ReturnType, *ResponseDict) {

	rd := new(ResponseDict)
	qname, err := dns.ReverseAddr(ipaddr)
	if err != nil {
		fmt.Printf("Invalid IP address: %s\n", ipaddr)
		return RETURN_GENERIC_ERROR, nil
	}

	reply, err := doQuery(ctx, qname, "PTR", "IN", ext)
	if err != nil {
		return RETURN_GENERIC_ERROR, rd // temporary
	}
	rd.RepliesTree = append(rd.RepliesTree, reply)
	return RETURN_GOOD, rd

}
Example #10
0
File: dns.go Project: fcavani/net
func LookupIp(ip string) (host string, err error) {
	if !utilNet.IsValidIpv4(ip) && !utilNet.IsValidIpv6(ip) {
		return "", e.New("not a valid ip address")
	}
	if ip == "127.0.0.1" || ip == "::1" {
		return "localhost", nil
	}
	config, err := dns.ClientConfigFromFile(ConfigurationFile)
	if err != nil {
		return "", e.Forward(err)
	}
	config.Timeout = Timeout

	c := new(dns.Client)
	c.DialTimeout = DialTimeout
	c.ReadTimeout = ReadTimeout
	c.WriteTimeout = WriteTimeout
	m := new(dns.Msg)
	rev, err := dns.ReverseAddr(ip)
	if err != nil {
		return "", e.Forward(err)
	}
	m.SetQuestion(rev, dns.TypePTR)
	var r *dns.Msg
	for i := 0; i < len(config.Servers); i++ {
		r, _, err = c.Exchange(m, config.Servers[i]+":"+config.Port)
		if err != nil {
			continue
		}
		err = nil
	}
	if err != nil {
		return "", e.Forward(err)
	}
	if r.Rcode != dns.RcodeSuccess {
		return "", e.New("can't resolve %v", ip)
	}

	for _, a := range r.Answer {
		if ptr, ok := a.(*dns.PTR); ok {
			return strings.TrimSuffix(ptr.Ptr, "."), nil
		}
	}
	return "", e.New("no ptr available")
}
Example #11
0
File: dns.go Project: ryansb/cjdcmd
// Lookup the hostname for an IP address using HypeDNS
// This probably needs work but I don't really know what I'm doing :)
func reverseHypeDNSLookup(ip string) (response string, err error) {
	c := new(dns.Client)

	m := new(dns.Msg)
	thing, err := dns.ReverseAddr(ip)
	if err != nil {
		return
	}
	m.SetQuestion(thing, dns.TypePTR)
	m.RecursionDesired = true

	r, _, err := c.Exchange(m, "[fc5d:baa5:61fc:6ffd:9554:67f0:e290:7535]:53")
	if r == nil || err != nil {
		return
	}

	// Stuff must be in the answer section
	for _, a := range r.Answer {
		columns := strings.Fields(a.String()) //column 4 holds the ip address
		return columns[4], nil
	}
	return
}
Example #12
0
func dnsLookup(msg commands.Message, ret commands.MessageFunc) string {
	var lookupType, lookupAddr string
	if len(msg.Params) < 2 {
		return "Usage: .dns [A/AAAA/CNAME/PTR/TXT/SRV] [host]"
	} else if len(msg.Params) == 2 {
		lookupType = "A"
		lookupAddr = msg.Params[1]
	} else {
		lookupType = msg.Params[1]
		lookupAddr = msg.Params[2]
	}
	if strings.ToUpper(lookupType) == "PTR" {
		if addr, err := dns.ReverseAddr(lookupAddr); err == nil {
			return lookupHelper(msg, ret, dns.TypePTR, addr)
		}
		return "Invalid PTR address"
	} else if _, isdomain := dns.IsDomainName(lookupAddr); isdomain {
		if querytype, ok := dns.StringToType[strings.ToUpper(lookupType)]; ok {
			return lookupHelper(msg, ret, querytype, lookupAddr)
		}
	}
	return ""
}
Example #13
0
func ptrName(address string) string {
	reverse, err := dns.ReverseAddr(address)
	if err != nil {
		return ""
	}

	m := &dns.Msg{}
	m.RecursionDesired = true
	m.SetQuestion(reverse, dns.TypePTR)

	// execute the query
	result, _, err := dnsClient.Exchange(m, net.JoinHostPort(referenceServer, "53"))
	if result == nil || result.Rcode != dns.RcodeSuccess {
		return ""
	}

	// Add addresses to set
	for _, a := range result.Answer {
		if record, ok := a.(*dns.PTR); ok {
			return record.Ptr
		}
	}
	return ""
}
Example #14
0
// http://dns.bortzmeyer.org/{+domain}/{querytype}{?format,server,buffersize,dodnssec,tcp,reverse
func handler(w http.ResponseWriter, r *http.Request, typ string) {
	var (
		dnstype uint16
		ok      bool
	)
	lg.Printf("request from %s %s\n", r.RemoteAddr, r.URL)
	if dnstype, ok = dns.StringToType[typ]; !ok {
		fmt.Fprintf(w, "Record type "+typ+" does not exist")
		return
	}
	domain := mux.Vars(r)["domain"]
	domain = html.UnescapeString(domain)

	u := unbound.New()
	defer u.Destroy()
	forward := false
	format := "html"
	u.SetOption("module-config:", "iterator")
	for k, v := range r.URL.Query() {
		switch k {
		case "tcp":
			if v[0] == "1" {
				u.SetOption("tcp-upstream:", "yes")
			}
		case "dodnssec":
			if v[0] == "1" {
				u.SetOption("module-config:", "validator iterator")
				u.SetOption("edns-buffer-size:", "4096")
				u.AddTa(`;; ANSWER SECTION:
.                       168307 IN DNSKEY 257 3 8 (
                                AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQ
                                bSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh
                                /RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWA
                                JQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXp
                                oY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3
                                LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGO
                                Yl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGc
                                LmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0=
                                ) ; key id = 19036`)
			}
		case "buffersize":
			if err := u.SetOption("edns-buffer-size:", v[0]); err != nil {
				fmt.Fprintf(w, "Not a valid buffer size: %s", v[0])
				return
			}
		case "server":
			if err := u.SetFwd(v[0]); err != nil {
				fmt.Fprintf(w, "Not a valid server `%s': %s", v[0], err.Error())
				return
			}
			forward = true
		case "reverse":
			if v[0] == "1" {
				var err error
				dnstype = dns.TypePTR
				domain, err = dns.ReverseAddr(domain)
				if err != nil {
					fmt.Fprintf(w, "Not a valid IP address: %s", v[0])
					return
				}
			}
		case "format": // unsupported format defaut to html
			for _, f := range []string{"html", "zone", "xml", "json", "text"} {
				if v[0] == f {
					format = f
				}
			}
		}
	}
	if !forward {
		u.ResolvConf("/etc/resolv.conf")
	}
	d, err := u.Resolve(domain, dnstype, dns.ClassINET)
	if err != nil {
		fmt.Fprintf(w, "error")
		return
	}
	if !d.HaveData {
		fmt.Fprintf(w, "Domain %s (type %s) does not exist", domain, dns.TypeToString[dnstype])
		return
	}
	switch format {
	case "json":
		Json(w, d)
	case "xml":
		Xml(w, d)
	case "html":
		fallthrough
	case "text":
		fallthrough
	case "zone":
		Zone(w, d)
	}
}