1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 func query(filename, query string, bufSize int) (res []string, err error) {
14 file, err := os.OpenFile(filename, os.O_RDWR, 0)
20 _, err = file.WriteString(query)
24 _, err = file.Seek(0, 0)
28 buf := make([]byte, bufSize)
30 n, _ := file.Read(buf)
34 res = append(res, string(buf[:n]))
39 func queryCS(net, host, service string) (res []string, err error) {
49 return query("/net/cs", net+"!"+host+"!"+service, 128)
52 func queryCS1(net string, ip IP, port int) (clone, dest string, err error) {
54 if len(ip) != 0 && !ip.IsUnspecified() {
57 lines, err := queryCS(net, ips, itoa(port))
61 f := getFields(lines[0])
63 return "", "", errors.New("net: bad response from ndb/cs")
65 clone, dest = f[0], f[1]
69 func queryDNS(addr string, typ string) (res []string, err error) {
70 return query("/net/dns", addr+" "+typ, 1024)
73 func lookupProtocol(name string) (proto int, err error) {
74 // TODO: Implement this
75 return 0, syscall.EPLAN9
78 func lookupHost(host string) (addrs []string, err error) {
79 // Use /net/cs instead of /net/dns because cs knows about
80 // host names in local network (e.g. from /lib/ndb/local)
81 lines, err := queryCS("tcp", host, "1")
85 for _, line := range lines {
91 if i := byteIndex(addr, '!'); i >= 0 {
92 addr = addr[:i] // remove port
94 if ParseIP(addr) == nil {
97 addrs = append(addrs, addr)
102 func lookupIP(host string) (ips []IP, err error) {
103 addrs, err := LookupHost(host)
107 for _, addr := range addrs {
108 if ip := ParseIP(addr); ip != nil {
109 ips = append(ips, ip)
115 func lookupPort(network, service string) (port int, err error) {
122 lines, err := queryCS(network, "127.0.0.1", service)
126 unknownPortError := &AddrError{"unknown port", network + "/" + service}
128 return 0, unknownPortError
130 f := getFields(lines[0])
132 return 0, unknownPortError
135 if i := byteIndex(s, '!'); i >= 0 {
136 s = s[i+1:] // remove address
138 if n, _, ok := dtoi(s, 0); ok {
141 return 0, unknownPortError
144 func lookupCNAME(name string) (cname string, err error) {
145 lines, err := queryDNS(name, "cname")
150 if f := getFields(lines[0]); len(f) >= 3 {
151 return f[2] + ".", nil
154 return "", errors.New("net: bad response from ndb/dns")
157 func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
159 if service == "" && proto == "" {
162 target = "_" + service + "._" + proto + "." + name
164 lines, err := queryDNS(target, "srv")
168 for _, line := range lines {
173 port, _, portOk := dtoi(f[2], 0)
174 priority, _, priorityOk := dtoi(f[3], 0)
175 weight, _, weightOk := dtoi(f[4], 0)
176 if !(portOk && priorityOk && weightOk) {
179 addrs = append(addrs, &SRV{f[5], uint16(port), uint16(priority), uint16(weight)})
182 byPriorityWeight(addrs).sort()
186 func lookupMX(name string) (mx []*MX, err error) {
187 lines, err := queryDNS(name, "mx")
191 for _, line := range lines {
196 if pref, _, ok := dtoi(f[2], 0); ok {
197 mx = append(mx, &MX{f[3], uint16(pref)})
204 func lookupNS(name string) (ns []*NS, err error) {
205 lines, err := queryDNS(name, "ns")
209 for _, line := range lines {
214 ns = append(ns, &NS{f[3]})
219 func lookupTXT(name string) (txt []string, err error) {
220 lines, err := queryDNS(name, "txt")
224 for _, line := range lines {
225 if i := byteIndex(line, '\t'); i >= 0 {
226 txt = append(txt, line[i+1:])
232 func lookupAddr(addr string) (name []string, err error) {
233 arpa, err := reverseaddr(addr)
237 lines, err := queryDNS(arpa, "ptr")
241 for _, line := range lines {
246 name = append(name, f[2])