summaryrefslogtreecommitdiff
path: root/internal/ioriotng.go
blob: a95892c2774cd0d38f4d178c9227daf3e98a6bf7 (plain)
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
package internal

import "C"

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"log"
	"runtime"

	"ioriotng/internal/debugfs"
	"ioriotng/internal/flags"
	"ioriotng/internal/tracepoints"
	"ioriotng/internal/types"

	bpf "github.com/aquasecurity/libbpfgo"
)

type BpfMapper interface {
	String() string
}

func Run(flags flags.Flags) {
	// To consider for implementation!
	log.Println(debugfs.TracepointsWithFd())

	bpfModule, err := bpf.NewModuleFromFile("ioriotng.bpf.o")
	if err != nil {
		log.Fatal(err)
	}
	defer bpfModule.Close()

	if err := flags.ResizeBPFMaps(bpfModule); err != nil {
		log.Fatal(err)
	}

	err = bpfModule.BPFLoadObject()
	if err != nil {
		log.Fatal(err)
	}

	if err := flags.SetBPF(bpfModule); err != nil {
		log.Fatal(err)
	}

	if err := tracepoints.AttachSyscalls(bpfModule); err != nil {
		log.Fatal(err)
	}

	ch := make(chan []byte)
	rb, err := bpfModule.InitRingBuf("event_map", ch)
	if err != nil {
		log.Fatal(err)
	}
	rb.Poll(300)

	for raw := range ch {
		switch types.OpId(raw[0]) {
		// TODO: Actually, need one ring buffer event per enter/exit ... otherwise may be difficult to capture
		// what belongs to what in event based / multiplexed applications.
		case types.OPENAT_ENTER_OP_ID:
			var ev types.OpenatEnterEvent
			if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &ev); err != nil {
				log.Fatal(err)
			}
			fmt.Println(ev)
		case types.OPENAT_EXIT_OP_ID:
			fallthrough
		case types.CLOSE_ENTER_OP_ID:
			var ev types.FdEvent
			if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &ev); err != nil {
				log.Fatal(err)
			}
			fmt.Println(ev)
		case types.CLOSE_EXIT_OP_ID:
			var ev types.NullEvent
			if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &ev); err != nil {
				log.Fatal(err)
			}
			fmt.Println(ev)
		default:
			panic(fmt.Sprintf("UNKNOWN Ringbuf data received len:%d raw:%v", len(raw), raw))
		}
	}

	log.Println("Good bye")
}

func ksymArch() string {
	switch runtime.GOARCH {
	case "amd64":
		return "x64"
	case "arm64":
		return "arm64"
	default:
		panic("unsupported architecture")
	}
}