-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
portlist.go
93 lines (80 loc) · 2.39 KB
/
portlist.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2014-present Datadog, Inc.
// Package portlist provides functionality to fetch open ports in the current machine.
package portlist
import (
"errors"
"github.com/DataDog/datadog-agent/pkg/util/log"
"path/filepath"
"runtime"
)
var (
newOSImpl func(cfg *config) osImpl
)
// Poller scans the systems for listening ports.
type Poller struct {
// os, if non-nil, is an OS-specific implementation of the portlist getting
// code. When non-nil, it's responsible for getting the complete list of
// cached ports complete with the process name. That is, when set,
// addProcesses is not used.
// A nil values means we don't have code for getting the list on the current
// operating system.
os osImpl
}
type config struct {
includeLocalhost bool
procMountPoint string
}
func newDefaultConfig() *config {
return &config{
includeLocalhost: false,
procMountPoint: "/proc",
}
}
// NewPoller initializes a new Poller.
func NewPoller(opts ...Option) (*Poller, error) {
if newOSImpl == nil {
return nil, errors.New("poller not implemented on " + runtime.GOOS)
}
cfg := newDefaultConfig()
for _, opt := range opts {
opt(cfg)
}
return &Poller{
os: newOSImpl(cfg),
}, nil
}
// osImpl is the OS-specific implementation of getting the open listening ports.
type osImpl interface {
Init()
Close() error
// OpenPorts returns the list of open ports. The Port struct should be
// populated as completely as possible.
OpenPorts() ([]Port, error)
}
// OpenPorts returns the list of currently listening ports.
func (p *Poller) OpenPorts() (List, error) {
p.os.Init()
defer func() {
if err := p.os.Close(); err != nil {
log.Warnf("failed to close port poller: %v", err)
}
}()
return p.os.OpenPorts()
}
// Option is used to configure the Poller.
type Option func(cfg *config)
// WithIncludeLocalhost allows to include/exclude localhost ports (false by default).
func WithIncludeLocalhost(includeLocalhost bool) Option {
return func(cfg *config) {
cfg.includeLocalhost = includeLocalhost
}
}
// WithProcMountPoint allows to change the proc filesystem mount point (this is used mainly in tests).
func WithProcMountPoint(mountPoint string) Option {
return func(cfg *config) {
cfg.procMountPoint = filepath.Clean(mountPoint)
}
}