// SPDX-License-Identifier: GPL-3.0-or-later // Package events implements the event-driven rule layer independently from // its eventual kernel source. Keeping event records and matching pure makes // Python/Go parity testable before cilium/ebpf enters the build. package events import ( "encoding/json" "strings" ) // ExecEvent is one execve observed at execution time. Argv excludes filename, // matching the Python event model and the current BCC source contract. type ExecEvent struct { PID int `json:"pid"` PPID int `json:"ppid"` UID int `json:"uid"` ParentComm string `json:"parent_comm"` Filename string `json:"filename"` Argv []string `json:"argv"` } // ExecComm intentionally mirrors posixpath.basename rather than filepath.Base: // Python returns an empty basename for a path ending in '/', while filepath // cleans the trailing separator and would return the previous component. func (e ExecEvent) ExecComm() string { if index := strings.LastIndex(e.Filename, "/"); index >= 0 { return e.Filename[index+1:] } return e.Filename } func (e ExecEvent) ArgvString() string { parts := make([]string, 0, len(e.Argv)+1) parts = append(parts, e.Filename) parts = append(parts, e.Argv...) return strings.TrimSpace(strings.Join(parts, " ")) } func (e *ExecEvent) UnmarshalJSON(raw []byte) error { var values map[string]any if err := json.Unmarshal(raw, &values); err != nil { return err } e.PID = integerValue(values["pid"], 0) e.PPID = integerValue(values["ppid"], 0) e.UID = integerValue(values["uid"], 0) e.ParentComm = stringValue(values["parent_comm"]) e.Filename = stringValue(values["filename"]) e.Argv = stringSlice(values["argv"]) return nil }