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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
package procmon
import (
"sync"
"time"
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
)
var (
cacheMonitorsRunning = false
lock = sync.RWMutex{}
monitorMethod = MethodProc
)
// monitor method supported types
const (
MethodProc = "proc"
MethodAudit = "audit"
MethodEbpf = "ebpf"
KernelConnection = "Kernel connection"
ProcSelf = "/proc/self/"
)
// man 5 proc; man procfs
type procIOstats struct {
RChar int64
WChar int64
SyscallRead int64
SyscallWrite int64
ReadBytes int64
WriteBytes int64
}
type procNetStats struct {
ReadBytes uint64
WriteBytes uint64
}
type procDescriptors struct {
ModTime time.Time
Name string
SymLink string
Size int64
}
type procStatm struct {
Size int64
Resident int64
Shared int64
Text int64
Lib int64
Data int64 // data + stack
Dt int
}
// Process holds the details of a process.
type Process struct {
Env map[string]string
IOStats *procIOstats
NetStats *procNetStats
Statm *procStatm
Maps string
// Path is the absolute path to the binary
Path string
Comm string
CWD string
Status string
Stat string
Stack string
Descriptors []*procDescriptors
// Args is the command that the user typed. It MAY contain the absolute path
// of the binary:
// $ curl https://...
// -> Path: /usr/bin/curl
// -> Args: curl https://....
// $ /usr/bin/curl https://...
// -> Path: /usr/bin/curl
// -> Args: /usr/bin/curl https://....
Args []string
ID int
PPID int
UID int
}
// NewProcess returns a new Process structure.
func NewProcess(pid int, comm string) *Process {
return &Process{
ID: pid,
Comm: comm,
Args: make([]string, 0),
Env: make(map[string]string),
IOStats: &procIOstats{},
NetStats: &procNetStats{},
Statm: &procStatm{},
}
}
// Serialize transforms a Process object to gRPC protocol object
func (p *Process) Serialize() *protocol.Process {
ioStats := p.IOStats
netStats := p.NetStats
if ioStats == nil {
ioStats = &procIOstats{}
}
if netStats == nil {
netStats = &procNetStats{}
}
return &protocol.Process{
Pid: uint64(p.ID),
Ppid: uint64(p.PPID),
Uid: uint64(p.UID),
Comm: p.Comm,
Path: p.Path,
Args: p.Args,
Env: p.Env,
Cwd: p.CWD,
IoReads: uint64(ioStats.RChar),
IoWrites: uint64(ioStats.WChar),
NetReads: netStats.ReadBytes,
NetWrites: netStats.WriteBytes,
}
}
// SetMonitorMethod configures a new method for parsing connections.
func SetMonitorMethod(newMonitorMethod string) {
lock.Lock()
defer lock.Unlock()
monitorMethod = newMonitorMethod
}
// GetMonitorMethod configures a new method for parsing connections.
func GetMonitorMethod() string {
lock.Lock()
defer lock.Unlock()
return monitorMethod
}
// MethodIsEbpf returns if the process monitor method is eBPF.
func MethodIsEbpf() bool {
lock.RLock()
defer lock.RUnlock()
return monitorMethod == MethodEbpf
}
// MethodIsAudit returns if the process monitor method is eBPF.
func MethodIsAudit() bool {
lock.RLock()
defer lock.RUnlock()
return monitorMethod == MethodAudit
}
func methodIsProc() bool {
lock.RLock()
defer lock.RUnlock()
return monitorMethod == MethodProc
}
|