opensnitch/daemon/procmon/parse.go

82 lines
1.8 KiB
Go

package procmon
import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/evilsocket/opensnitch/daemon/core"
)
func GetPIDFromINode(inode int) int {
expect := fmt.Sprintf("socket:[%d]", inode)
found := -1
forEachProcess(func(pid int, path string, args []string) bool {
// for every descriptor
fdPath := fmt.Sprintf("/proc/%d/fd/", pid)
if descriptors, err := ioutil.ReadDir(fdPath); err == nil {
for _, desc := range descriptors {
descLink := fmt.Sprintf("%s%s", fdPath, desc.Name())
// resolve the symlink and compare to what we expect
if link, err := os.Readlink(descLink); err == nil && link == expect {
found = pid
return true
}
}
}
// keep looping
return false
})
return found
}
func parseCmdLine(proc *Process) {
if data, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", proc.ID)); err == nil {
for i, b := range data {
if b == 0x00 {
data[i] = byte(' ')
}
}
args := strings.Split(string(data), " ")
for _, arg := range args {
arg = core.Trim(arg)
if arg != "" {
proc.Args = append(proc.Args, arg)
}
}
}
}
func parseEnv(proc *Process) {
if data, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/environ", proc.ID)); err == nil {
for _, s := range strings.Split(string(data), "\x00") {
parts := strings.SplitN(core.Trim(s), "=", 2)
if parts != nil && len(parts) == 2 {
key := core.Trim(parts[0])
val := core.Trim(parts[1])
proc.Env[key] = val
}
}
}
}
func FindProcess(pid int) *Process {
linkName := fmt.Sprintf("/proc/%d/exe", pid)
if core.Exists(linkName) == false {
return nil
}
if link, err := os.Readlink(linkName); err == nil && core.Exists(link) == true {
proc := NewProcess(pid, link)
parseCmdLine(proc)
parseEnv(proc)
return proc
}
return nil
}