github.com/castai/kvisor@v1.7.1-0.20240516114728-b3572a2607b5/pkg/ebpftracer/types/protocol.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/castai/kvisor/pkg/ebpftracer/events"
     7  	"golang.org/x/sys/unix"
     8  )
     9  
    10  // BinType is an enum that specifies the type of binary data sent in the file perf map
    11  // binary types should match defined values in ebpf code
    12  type BinType uint8
    13  
    14  const (
    15  	SendVfsWrite BinType = iota + 1
    16  	SendMprotect
    17  	SendKernelModule
    18  	SendBpfObject
    19  	SendVfsRead
    20  )
    21  
    22  // PLEASE NOTE, YOU MUST UPDATE THE DECODER IF ANY CHANGE TO THIS STRUCT IS DONE.
    23  type SignalContext struct {
    24  	EventID events.ID // uint32
    25  }
    26  
    27  func (SignalContext) GetSizeBytes() int {
    28  	return 4
    29  }
    30  
    31  // PLEASE NOTE, YOU MUST UPDATE THE DECODER IF ANY CHANGE TO THIS STRUCT IS DONE.
    32  
    33  // EventContext struct contains common metadata that is collected for all types of events
    34  // it is used to unmarshal binary data and therefore should match (bit by bit) to the `context_t` struct in the ebpf code.
    35  // NOTE: Integers want to be aligned in memory, so if changing the format of this struct
    36  // keep the 1-byte 'Argnum' as the final parameter before the padding (if padding is needed).
    37  type EventContext struct {
    38  	Ts        uint64
    39  	StartTime uint64
    40  	CgroupID  uint64
    41  	Pid       uint32
    42  	Tid       uint32
    43  	Ppid      uint32
    44  	HostPid   uint32
    45  	HostTid   uint32
    46  	HostPpid  uint32
    47  	// PID translated to PIDNS the container runtime is running in
    48  	NodeHostPid     uint32
    49  	Uid             uint32
    50  	MntID           uint32
    51  	PidID           uint32
    52  	Comm            [16]byte
    53  	UtsName         [16]byte
    54  	Flags           uint32
    55  	LeaderStartTime uint64
    56  	ParentStartTime uint64
    57  	_               [4]byte   // padding
    58  	EventID         events.ID // uint32
    59  	Syscall         int32
    60  	MatchedPolicies uint64
    61  	Retval          int64
    62  	StackID         uint32
    63  	ProcessorId     uint16
    64  	_               [2]byte // padding
    65  }
    66  
    67  func (ctx *EventContext) GetFlowDirection() FlowDirection {
    68  	if ctx.Retval&FlagPacketIngress > 0 && ctx.Retval&FlagPacketEgress > 0 {
    69  		// something is broken if both ingress and egress flags are set
    70  		return FlowDirectionUnknown
    71  	}
    72  
    73  	if ctx.Retval&FlagPacketIngress > 0 {
    74  		return FlowDirectionIngress
    75  	}
    76  	if ctx.Retval&FlagPacketEgress > 0 {
    77  		return FlowDirectionEgress
    78  	}
    79  
    80  	return FlowDirectionUnknown
    81  }
    82  
    83  func (ctx *EventContext) GetNetflowType() NetflowType {
    84  	if ctx.Retval&FlagFlowTCPBegin > 0 {
    85  		return NetflowTypeTCPBegin
    86  	}
    87  	if ctx.Retval&FlagFlowTCPSample > 0 {
    88  		return NetflowTypeTCPSample
    89  	}
    90  	if ctx.Retval&FlagFlowTCPEnd > 0 {
    91  		return NetflowTypeTCPEnd
    92  	}
    93  	return NetflowTypeUnknown
    94  }
    95  
    96  func (ctx *EventContext) IsSourceInitiator() bool {
    97  	if ctx.Retval&FlagFlowSrcInitiator > 0 {
    98  		return true
    99  	}
   100  	return false
   101  }
   102  
   103  func (EventContext) GetSizeBytes() int {
   104  	return 152
   105  }
   106  
   107  type ChunkMeta struct {
   108  	BinType  BinType
   109  	CgroupID uint64
   110  	Metadata [28]byte
   111  	Size     int32
   112  	Off      uint64
   113  }
   114  
   115  func (ChunkMeta) GetSizeBytes() uint32 {
   116  	return 49
   117  }
   118  
   119  type VfsFileMeta struct {
   120  	DevID uint32
   121  	Inode uint64
   122  	Mode  uint32
   123  	Pid   uint32
   124  }
   125  
   126  func (VfsFileMeta) GetSizeBytes() uint32 {
   127  	return 20
   128  }
   129  
   130  type KernelModuleMeta struct {
   131  	DevID uint32
   132  	Inode uint64
   133  	Pid   uint32
   134  	Size  uint32
   135  }
   136  
   137  func (KernelModuleMeta) GetSizeBytes() uint32 {
   138  	return 20
   139  }
   140  
   141  type BpfObjectMeta struct {
   142  	Name [16]byte
   143  	Rand uint32
   144  	Pid  uint32
   145  	Size uint32
   146  }
   147  
   148  func (BpfObjectMeta) GetSizeBytes() uint32 {
   149  	return 28
   150  }
   151  
   152  type MprotectWriteMeta struct {
   153  	Ts  uint64
   154  	Pid uint32
   155  }
   156  
   157  func (MprotectWriteMeta) GetSizeBytes() uint32 {
   158  	return 12
   159  }
   160  
   161  // SlimCred struct is a slim version of the kernel's cred struct
   162  // it is used to unmarshal binary data and therefore should match (bit by bit) to the `slim_cred_t` struct in the ebpf code.
   163  // ANY CHANGE TO THIS STRUCT WILL BE REQUIRED ALSO TO detect.SlimCred and bufferdecoder.SlimCred
   164  type SlimCred struct {
   165  	Uid            uint32 /* real UID of the task */
   166  	Gid            uint32 /* real GID of the task */
   167  	Suid           uint32 /* saved UID of the task */
   168  	Sgid           uint32 /* saved GID of the task */
   169  	Euid           uint32 /* effective UID of the task */
   170  	Egid           uint32 /* effective GID of the task */
   171  	Fsuid          uint32 /* UID for VFS ops */
   172  	Fsgid          uint32 /* GID for VFS ops */
   173  	UserNamespace  uint32 /* User Namespace of the of the event */
   174  	SecureBits     uint32 /* SUID-less security management */
   175  	CapInheritable uint64 /* caps our children can inherit */
   176  	CapPermitted   uint64 /* caps we're permitted */
   177  	CapEffective   uint64 /* caps we can actually use */
   178  	CapBounding    uint64 /* capability bounding set */
   179  	CapAmbient     uint64 /* Ambient capability set */
   180  }
   181  
   182  func (s SlimCred) GetSizeBytes() uint32 {
   183  	return 80
   184  }
   185  
   186  // RawDebugEvent is used to output debug from ebpf to userspace via perf array buf.
   187  type RawDebugEvent struct {
   188  	PID       uint32
   189  	TID       uint32
   190  	Timestamp uint64
   191  	CgroupID  uint64
   192  	Name      [16]byte
   193  	TaskComm  [16]byte
   194  	Arg1      uint64
   195  	Arg2      uint64
   196  	Arg3      uint64
   197  	Arg4      uint64
   198  	//SockAddr  uint64
   199  	//Tuple     rawTuple
   200  }
   201  
   202  func (e *RawDebugEvent) String() string {
   203  	args := []any{
   204  		e.Timestamp,
   205  		unix.ByteSliceToString(e.Name[:]),
   206  		e.PID,
   207  		e.CgroupID,
   208  		unix.ByteSliceToString(e.TaskComm[:]),
   209  	}
   210  	tmpl := "DEBUG[%d]: [%s] pid=%d cgroup=%d process=%s"
   211  	if e.Arg1 > 0 {
   212  		tmpl += " arg1=%d"
   213  		args = append(args, e.Arg1)
   214  	}
   215  	if e.Arg2 > 0 {
   216  		tmpl += " arg2=%d"
   217  		args = append(args, e.Arg2)
   218  	}
   219  	if e.Arg3 > 0 {
   220  		tmpl += " arg3=%d"
   221  		args = append(args, e.Arg3)
   222  	}
   223  	if e.Arg4 > 0 {
   224  		tmpl += " arg4=%d"
   225  		args = append(args, e.Arg4)
   226  	}
   227  	//if e.SockAddr > 0 {
   228  	//	tmpl += " sock=%d"
   229  	//	args = append(args, e.SockAddr)
   230  	//
   231  	//	tmpl += " %s -> %s"
   232  	//	src := ipPort(e.Tuple.Family, e.Tuple.Saddr, e.Tuple.Sport)
   233  	//	dst := ipPort(e.Tuple.Family, e.Tuple.Daddr, e.Tuple.Dport)
   234  	//	args = append(args, src, dst)
   235  	//}
   236  	return fmt.Sprintf(tmpl, args...)
   237  }
   238  
   239  const (
   240  	FlagFamilyIPv4 int64 = (1 << 0)
   241  	FlagFamilyIPv6       = (1 << 1)
   242  	// HTTP Direction (request/response) Flag
   243  	FlagProtoHTTPReq  = (1 << 2)
   244  	FlagProtoHTTPResp = (1 << 3)
   245  	// Packet Direction (ingress/egress) Flag
   246  	FlagPacketIngress = (1 << 4)
   247  	FlagPacketEgress  = (1 << 5)
   248  	// Flows (begin/end) Flags per Protocol
   249  	FlagFlowTCPBegin     = (1 << 6)  // syn+ack flag or first flow packet
   250  	FlagFlowTCPSample    = (1 << 7)  // tcp flow sample
   251  	FlagFlowTCPEnd       = (1 << 8)  // fin flag or last flow packet
   252  	FlagFlowUDPBegin     = (1 << 9)  // first flow packet
   253  	FlagFlowUDPEnd       = (1 << 10) // last flow packet
   254  	FlagFlowSrcInitiator = (1 << 11) // src is the flow initiator
   255  )