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. 4 5// +build darwin dragonfly freebsd linux netbsd openbsd 6 7package net 8 9import ( 10 "errors" 11 "sync" 12) 13 14var onceReadProtocols sync.Once 15 16// readProtocols loads contents of /etc/protocols into protocols map 17// for quick access. 18func readProtocols() { 19 if file, err := open("/etc/protocols"); err == nil { 20 for line, ok := file.readLine(); ok; line, ok = file.readLine() { 21 // tcp 6 TCP # transmission control protocol 22 if i := byteIndex(line, '#'); i >= 0 { 23 line = line[0:i] 24 } 25 f := getFields(line) 26 if len(f) < 2 { 27 continue 28 } 29 if proto, _, ok := dtoi(f[1], 0); ok { 30 if _, ok := protocols[f[0]]; !ok { 31 protocols[f[0]] = proto 32 } 33 for _, alias := range f[2:] { 34 if _, ok := protocols[alias]; !ok { 35 protocols[alias] = proto 36 } 37 } 38 } 39 } 40 file.close() 41 } 42} 43 44// lookupProtocol looks up IP protocol name in /etc/protocols and 45// returns correspondent protocol number. 46func lookupProtocol(name string) (proto int, err error) { 47 onceReadProtocols.Do(readProtocols) 48 proto, found := protocols[name] 49 if !found { 50 return 0, errors.New("unknown IP protocol specified: " + name) 51 } 52 return 53} 54 55func lookupHost(host string) (addrs []string, err error) { 56 addrs, err, ok := cgoLookupHost(host) 57 if !ok { 58 addrs, err = goLookupHost(host) 59 } 60 return 61} 62 63func lookupIP(host string) (addrs []IP, err error) { 64 addrs, err, ok := cgoLookupIP(host) 65 if !ok { 66 addrs, err = goLookupIP(host) 67 } 68 return 69} 70 71func lookupPort(network, service string) (port int, err error) { 72 port, err, ok := cgoLookupPort(network, service) 73 if !ok { 74 port, err = goLookupPort(network, service) 75 } 76 return 77} 78 79func lookupCNAME(name string) (cname string, err error) { 80 cname, err, ok := cgoLookupCNAME(name) 81 if !ok { 82 cname, err = goLookupCNAME(name) 83 } 84 return 85} 86 87func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) { 88 var target string 89 if service == "" && proto == "" { 90 target = name 91 } else { 92 target = "_" + service + "._" + proto + "." + name 93 } 94 var records []dnsRR 95 cname, records, err = lookup(target, dnsTypeSRV) 96 if err != nil { 97 return 98 } 99 addrs = make([]*SRV, len(records)) 100 for i, rr := range records { 101 r := rr.(*dnsRR_SRV) 102 addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight} 103 } 104 byPriorityWeight(addrs).sort() 105 return 106} 107 108func lookupMX(name string) (mx []*MX, err error) { 109 _, records, err := lookup(name, dnsTypeMX) 110 if err != nil { 111 return 112 } 113 mx = make([]*MX, len(records)) 114 for i, rr := range records { 115 r := rr.(*dnsRR_MX) 116 mx[i] = &MX{r.Mx, r.Pref} 117 } 118 byPref(mx).sort() 119 return 120} 121 122func lookupNS(name string) (ns []*NS, err error) { 123 _, records, err := lookup(name, dnsTypeNS) 124 if err != nil { 125 return 126 } 127 ns = make([]*NS, len(records)) 128 for i, r := range records { 129 r := r.(*dnsRR_NS) 130 ns[i] = &NS{r.Ns} 131 } 132 return 133} 134 135func lookupTXT(name string) (txt []string, err error) { 136 _, records, err := lookup(name, dnsTypeTXT) 137 if err != nil { 138 return 139 } 140 txt = make([]string, len(records)) 141 for i, r := range records { 142 txt[i] = r.(*dnsRR_TXT).Txt 143 } 144 return 145} 146 147func lookupAddr(addr string) (name []string, err error) { 148 name = lookupStaticAddr(addr) 149 if len(name) > 0 { 150 return 151 } 152 var arpa string 153 arpa, err = reverseaddr(addr) 154 if err != nil { 155 return 156 } 157 var records []dnsRR 158 _, records, err = lookup(arpa, dnsTypePTR) 159 if err != nil { 160 return 161 } 162 name = make([]string, len(records)) 163 for i := range records { 164 r := records[i].(*dnsRR_PTR) 165 name[i] = r.Ptr 166 } 167 return 168} 169