github.com/cilium/cilium@v1.16.2/pkg/proxy/netstat.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package proxy 5 6 import ( 7 "bytes" 8 "os" 9 "regexp" 10 "strconv" 11 12 "github.com/cilium/cilium/pkg/logging/logfields" 13 ) 14 15 var ( 16 // procNetTCPFiles is the constant list of /proc/net files to read to get 17 // the same information about open TCP connections as output by netstat. 18 procNetTCPFiles = []string{ 19 "/proc/net/tcp", 20 "/proc/net/tcp6", 21 } 22 23 // procNetUDPFiles is the constant list of /proc/net files to read to get 24 // the same information about open UDP connections as output by netstat. 25 procNetUDPFiles = []string{ 26 "/proc/net/udp", 27 "/proc/net/udp6", 28 } 29 30 // procNetFileRegexp matches the first two columns of /proc/net/{tcp,udp}* 31 // files and submatches on the local port number. 32 procNetFileRegexp = regexp.MustCompile("^ *[[:digit:]]*: *[[:xdigit:]]*:([[:xdigit:]]*) ") 33 ) 34 35 // readOpenLocalPorts returns the set of L4 ports currently open locally. 36 // procNetFiles should be procNetTCPFiles or procNetUDPFiles (or both). 37 func readOpenLocalPorts(procNetFiles []string) map[uint16]struct{} { 38 openLocalPorts := make(map[uint16]struct{}, 128) 39 40 for _, file := range procNetFiles { 41 b, err := os.ReadFile(file) 42 if err != nil { 43 log.WithError(err).WithField(logfields.Path, file).Errorf("cannot read proc file") 44 continue 45 } 46 47 lines := bytes.Split(b, []byte("\n")) 48 49 // Extract the local port number from the "local_address" column. 50 // The header line won't match and will be ignored. 51 for _, line := range lines { 52 groups := procNetFileRegexp.FindSubmatch(line) 53 if len(groups) != 2 { // no match 54 continue 55 } 56 // The port number is in hexadecimal. 57 localPort, err := strconv.ParseUint(string(groups[1]), 16, 16) 58 if err != nil { 59 log.WithError(err).WithField(logfields.Path, file).Errorf("cannot read proc file") 60 continue 61 } 62 openLocalPorts[uint16(localPort)] = struct{}{} 63 } 64 } 65 66 return openLocalPorts 67 } 68 69 // OpenLocalPorts returns the set of L4 ports currently open locally. 70 func OpenLocalPorts() map[uint16]struct{} { 71 return readOpenLocalPorts(append(procNetTCPFiles, procNetUDPFiles...)) 72 }