diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-19 10:12:32 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-19 10:12:32 +0300 |
| commit | 127516b4bf63dc922df222825a9a6a1d7eacc214 (patch) | |
| tree | 3839a2f6a7f4f1bc713690678fc003d4e2be8a8c /internal/generate | |
| parent | 32a19cf9fb1344c9b1a61054d7cf2c90edc3708a (diff) | |
u6: add socket/socketpair kind scaffolding and wiring
Diffstat (limited to 'internal/generate')
| -rw-r--r-- | internal/generate/bpfhandler.go | 12 | ||||
| -rw-r--r-- | internal/generate/classify.go | 6 | ||||
| -rw-r--r-- | internal/generate/classify_test.go | 17 | ||||
| -rw-r--r-- | internal/generate/codegen_test.go | 28 | ||||
| -rw-r--r-- | internal/generate/kindregistry.go | 2 | ||||
| -rw-r--r-- | internal/generate/testdata.go | 31 |
6 files changed, 91 insertions, 5 deletions
diff --git a/internal/generate/bpfhandler.go b/internal/generate/bpfhandler.go index 549e80b..6c9c314 100644 --- a/internal/generate/bpfhandler.go +++ b/internal/generate/bpfhandler.go @@ -73,6 +73,10 @@ func generateExtra(tp GeneratedTracepoint, isEnter bool) string { return " ev->fd = (__s32)ctx->args[0];\n ev->flags = (__s32)ctx->args[2];\n" case KindOpenByHandleAt: return " ev->flags = (__s32)ctx->args[2];\n" + case KindSocket: + return generateExtraSocket() + case KindSocketpair: + return generateExtraSocketpair() case KindOpen: return generateExtraOpen(f) case KindPathname: @@ -149,6 +153,14 @@ func generateExtraFcntl(f *Format) string { ) } +func generateExtraSocket() string { + return " ev->family = (__s32)ctx->args[0];\n ev->type = (__s32)ctx->args[1];\n ev->protocol = (__s32)ctx->args[2];\n" +} + +func generateExtraSocketpair() string { + return " int sv[2];\n __builtin_memset(&sv, 0xff, sizeof(sv));\n if (ctx->args[3] != 0) {\n bpf_probe_read_user(&sv, sizeof(sv), (void *)ctx->args[3]);\n }\n ev->family = (__s32)ctx->args[0];\n ev->type = (__s32)ctx->args[1];\n ev->protocol = (__s32)ctx->args[2];\n ev->sv0 = (__s32)sv[0];\n ev->sv1 = (__s32)sv[1];\n" +} + // eventStructName returns the C struct name for a TracepointKind. The mapping // is driven by kindRegistry so adding a new kind only requires a registry entry. func eventStructName(kind TracepointKind) string { diff --git a/internal/generate/classify.go b/internal/generate/classify.go index 7768ea7..68cd722 100644 --- a/internal/generate/classify.go +++ b/internal/generate/classify.go @@ -15,6 +15,8 @@ const ( KindNull KindDup3 KindOpenByHandleAt + KindSocket + KindSocketpair ) type RetClassification string @@ -79,6 +81,10 @@ func classifyNameOnly(name string) (ClassificationResult, bool) { return ClassificationResult{Kind: KindNull}, true case "sys_enter_getcwd": return ClassificationResult{Kind: KindNull}, true + case "sys_enter_socket": + return ClassificationResult{Kind: KindSocket}, true + case "sys_enter_socketpair": + return ClassificationResult{Kind: KindSocketpair}, true } if strings.HasPrefix(name, "sys_enter_io_") { return ClassificationResult{Kind: KindNull}, true diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go index ea7d662..ce6eff1 100644 --- a/internal/generate/classify_test.go +++ b/internal/generate/classify_test.go @@ -244,10 +244,17 @@ func TestClassifyFdAccept(t *testing.T) { } } -func TestClassifySocketRequiresGenerationFallback(t *testing.T) { +func TestClassifySocket(t *testing.T) { r := classifyFromData(t, FormatSocket) - if r.Kind != KindNone { - t.Errorf("socket: got kind %d, want KindNone before generation fallback", r.Kind) + if r.Kind != KindSocket { + t.Errorf("socket: got kind %d, want KindSocket", r.Kind) + } +} + +func TestClassifySocketpair(t *testing.T) { + r := classifyFromData(t, FormatSocketpair) + if r.Kind != KindSocketpair { + t.Errorf("socketpair: got kind %d, want KindSocketpair", r.Kind) } } @@ -288,7 +295,8 @@ func TestClassifySyscallPairAccepted(t *testing.T) { {"mknod", FormatMknod, FormatExitMknod, KindPathname}, {"execve", FormatExecve, FormatExitExecve, KindPathname}, {"accept", FormatAccept, FormatExitAccept, KindFd}, - {"socket", FormatSocket, FormatExitSocket, KindNull}, + {"socket", FormatSocket, FormatExitSocket, KindSocket}, + {"socketpair", FormatSocketpair, FormatExitSocketpair, KindSocketpair}, {"kill", FormatKill, FormatExitKill, KindNull}, } @@ -314,6 +322,7 @@ func TestClassifySyscallPairEmitsAllFamilies(t *testing.T) { {"execve", FormatExecve, FormatExitExecve, FamilyProcess}, {"accept", FormatAccept, FormatExitAccept, FamilyNetwork}, {"socket", FormatSocket, FormatExitSocket, FamilyNetwork}, + {"socketpair", FormatSocketpair, FormatExitSocketpair, FamilyNetwork}, {"kill", FormatKill, FormatExitKill, FamilySignals}, } diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go index a448162..f87a6dc 100644 --- a/internal/generate/codegen_test.go +++ b/internal/generate/codegen_test.go @@ -185,6 +185,28 @@ func TestGenerateOpenByHandleAtHandler(t *testing.T) { requireContains(t, output, "ev->flags = (__s32)ctx->args[2];") } +func TestGenerateSocketHandler(t *testing.T) { + output := generateFromPair(t, FormatSocket, FormatExitSocket) + + requireContains(t, output, "struct socket_event *ev") + requireContains(t, output, "ev->event_type = ENTER_SOCKET_EVENT;") + requireContains(t, output, "ev->family = (__s32)ctx->args[0];") + requireContains(t, output, "ev->type = (__s32)ctx->args[1];") + requireContains(t, output, "ev->protocol = (__s32)ctx->args[2];") +} + +func TestGenerateSocketpairHandler(t *testing.T) { + output := generateFromPair(t, FormatSocketpair, FormatExitSocketpair) + + requireContains(t, output, "struct socketpair_event *ev") + requireContains(t, output, "ev->event_type = ENTER_SOCKETPAIR_EVENT;") + requireContains(t, output, "int sv[2];") + requireContains(t, output, "bpf_probe_read_user(&sv, sizeof(sv), (void *)ctx->args[3]);") + requireContains(t, output, "ev->family = (__s32)ctx->args[0];") + requireContains(t, output, "ev->sv0 = (__s32)sv[0];") + requireContains(t, output, "ev->sv1 = (__s32)sv[1];") +} + func TestGenerateNameToHandleAtHandler(t *testing.T) { output := generateFromPair(t, FormatNameToHandleAt, FormatExitNameToHandleAt) @@ -292,6 +314,8 @@ func TestGenerateAllEventTypes(t *testing.T) { {KindNull, "ENTER_NULL_EVENT", "EXIT_NULL_EVENT"}, {KindDup3, "ENTER_DUP3_EVENT", "EXIT_DUP3_EVENT"}, {KindOpenByHandleAt, "ENTER_OPEN_BY_HANDLE_AT_EVENT", "EXIT_OPEN_BY_HANDLE_AT_EVENT"}, + {KindSocket, "ENTER_SOCKET_EVENT", "EXIT_SOCKET_EVENT"}, + {KindSocketpair, "ENTER_SOCKETPAIR_EVENT", "EXIT_SOCKETPAIR_EVENT"}, } for _, tt := range tests { @@ -318,6 +342,8 @@ func TestEventStructNames(t *testing.T) { {KindNull, "null_event"}, {KindDup3, "dup3_event"}, {KindOpenByHandleAt, "open_by_handle_at_event"}, + {KindSocket, "socket_event"}, + {KindSocketpair, "socketpair_event"}, } for _, tt := range tests { @@ -336,7 +362,7 @@ func TestEnterReject(t *testing.T) { t.Error("KindNone should be enter-rejected") } - accepted := []TracepointKind{KindFd, KindOpen, KindPathname, KindName, KindFcntl, KindNull, KindDup3, KindOpenByHandleAt} + accepted := []TracepointKind{KindFd, KindOpen, KindPathname, KindName, KindFcntl, KindNull, KindDup3, KindOpenByHandleAt, KindSocket, KindSocketpair} for _, k := range accepted { if isEnterRejected(k) { t.Errorf("kind %d should NOT be enter-rejected", k) diff --git a/internal/generate/kindregistry.go b/internal/generate/kindregistry.go index 86b77aa..f716489 100644 --- a/internal/generate/kindregistry.go +++ b/internal/generate/kindregistry.go @@ -25,6 +25,8 @@ var kindRegistry = map[TracepointKind]kindMeta{ KindNull: {structName: "null_event", enterAccepted: true}, KindDup3: {structName: "dup3_event", enterAccepted: true}, KindOpenByHandleAt: {structName: "open_by_handle_at_event", enterAccepted: true}, + KindSocket: {structName: "socket_event", enterAccepted: true}, + KindSocketpair: {structName: "socketpair_event", enterAccepted: true}, // KindNone is intentionally absent: it represents "unclassified" and is // never enter-accepted. lookupKind returns the zero kindMeta (enterAccepted=false) // for any unregistered kind, so KindNone is implicitly rejected. diff --git a/internal/generate/testdata.go b/internal/generate/testdata.go index a9bedc6..e363a68 100644 --- a/internal/generate/testdata.go +++ b/internal/generate/testdata.go @@ -823,6 +823,37 @@ format: print fmt: "0x%lx", REC->ret ` +const FormatSocketpair = `name: sys_enter_socketpair +ID: 1816 +format: + field:unsigned short common_type; offset:0; size:2; signed:0; + field:unsigned char common_flags; offset:2; size:1; signed:0; + field:unsigned char common_preempt_count; offset:3; size:1; signed:0; + field:int common_pid; offset:4; size:4; signed:1; + + field:int __syscall_nr; offset:8; size:4; signed:1; + field:int family; offset:16; size:8; signed:0; + field:int type; offset:24; size:8; signed:0; + field:int protocol; offset:32; size:8; signed:0; + field:int * usockvec; offset:40; size:8; signed:0; + +print fmt: "family: 0x%08lx, type: 0x%08lx, protocol: 0x%08lx, usockvec: 0x%08lx", ((unsigned long)(REC->family)), ((unsigned long)(REC->type)), ((unsigned long)(REC->protocol)), ((unsigned long)(REC->usockvec)) +` + +const FormatExitSocketpair = `name: sys_exit_socketpair +ID: 1815 +format: + field:unsigned short common_type; offset:0; size:2; signed:0; + field:unsigned char common_flags; offset:2; size:1; signed:0; + field:unsigned char common_preempt_count; offset:3; size:1; signed:0; + field:int common_pid; offset:4; size:4; signed:1; + + field:int __syscall_nr; offset:8; size:4; signed:1; + field:long ret; offset:16; size:8; signed:1; + +print fmt: "0x%lx", REC->ret +` + const FormatPread64 = `name: sys_enter_pread64 ID: 840 format: |
