1// Copyright 2009 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//go:build unix || js || wasip1
6
7// Read system port mappings from /etc/services
8
9package net
10
11import (
12	"internal/bytealg"
13	"sync"
14)
15
16var onceReadServices sync.Once
17
18func readServices() {
19	file, err := open("/etc/services")
20	if err != nil {
21		return
22	}
23	defer file.close()
24
25	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
26		// "http 80/tcp www www-http # World Wide Web HTTP"
27		if i := bytealg.IndexByteString(line, '#'); i >= 0 {
28			line = line[:i]
29		}
30		f := getFields(line)
31		if len(f) < 2 {
32			continue
33		}
34		portnet := f[1] // "80/tcp"
35		port, j, ok := dtoi(portnet)
36		if !ok || port <= 0 || j >= len(portnet) || portnet[j] != '/' {
37			continue
38		}
39		netw := portnet[j+1:] // "tcp"
40		m, ok1 := services[netw]
41		if !ok1 {
42			m = make(map[string]int)
43			services[netw] = m
44		}
45		for i := 0; i < len(f); i++ {
46			if i != 1 { // f[1] was port/net
47				m[f[i]] = port
48			}
49		}
50	}
51}
52
53// goLookupPort is the native Go implementation of LookupPort.
54func goLookupPort(network, service string) (port int, err error) {
55	onceReadServices.Do(readServices)
56	return lookupPortMap(network, service)
57}
58