Skip to content

Commit c394437

Browse files
committed
feat: add tcpconnect tool for monitoring TCP connections
Introduced a new eBPF-based tool, tcpconnect, that monitors TCP connection attempts in real-time. The tool captures process information, source and destination IP addresses, and ports for each connection. Updated the Makefile to include the new command and added relevant documentation for usage and implementation details. Enhanced .gitignore to exclude new video production files.
1 parent 0ea02a5 commit c394437

File tree

7 files changed

+740
-3
lines changed

7 files changed

+740
-3
lines changed

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,10 @@ ebee
4444
.Trashes
4545
ehthumbs.db
4646
Thumbs.db
47-
venv/
47+
venv/
48+
49+
# Video production files (private content)
50+
video-scripts/
51+
video-production-plan.md
52+
video-production-templates.md
53+
intro-video-script.md

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ gen_vmlinux:
3737
generate:
3838
go generate ./cmd/rmdetect.go
3939
go generate ./cmd/execsnoop.go
40+
go generate ./cmd/tcpconnect.go
4041

4142
# Build the ebee CLI application
4243
build: generate
@@ -60,6 +61,9 @@ run-rmdetect: build
6061
run-execsnoop: build
6162
sudo ./ebee execsnoop
6263

64+
run-tcpconnect: build
65+
sudo ./ebee tcpconnect
66+
6367
# Create new tool boilerplate
6468
create-tool:
6569
@echo "Creating new eBPF tool..."

bpf/tcpconnect.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "common.h"
2+
3+
#define AF_INET 2
4+
5+
// Define PT_REGS_PARM1 for x86_64 (first function parameter is in RDI register)
6+
#define PT_REGS_PARM1(x) ((x)->di)
7+
8+
struct tcp_connect_data_t {
9+
u32 pid; // Process ID making the connection
10+
u32 tgid; // Thread group ID
11+
char comm[16]; // Command name
12+
u32 saddr; // Source IP address (IPv4)
13+
u32 daddr; // Destination IP address (IPv4)
14+
u16 sport; // Source port
15+
u16 dport; // Destination port
16+
u64 timestamp; // Connection timestamp
17+
};
18+
19+
// Define the ring buffer
20+
struct {
21+
__uint(type, BPF_MAP_TYPE_RINGBUF);
22+
__uint(max_entries, 1 << 24); // 16MB buffer
23+
} events SEC(".maps");
24+
25+
// Alternative approach: Use syscall tracepoint which has structured data
26+
SEC("tracepoint/syscalls/sys_enter_connect")
27+
int trace_sys_connect(struct trace_event_raw_sys_enter *ctx) {
28+
// Check if this is a TCP socket by examining the sockaddr
29+
u64 fd = ctx->args[0];
30+
u64 sockaddr_ptr = ctx->args[1];
31+
u64 socklen = ctx->args[2];
32+
33+
// Basic sanity checks
34+
if (socklen < 16) { // sizeof(struct sockaddr_in)
35+
return 0;
36+
}
37+
38+
// Reserve space in the ring buffer
39+
struct tcp_connect_data_t *data = bpf_ringbuf_reserve(&events, sizeof(struct tcp_connect_data_t), 0);
40+
if (!data) {
41+
return 0;
42+
}
43+
44+
// Get current process information
45+
u64 pid_tgid = bpf_get_current_pid_tgid();
46+
data->pid = pid_tgid & 0xFFFFFFFF;
47+
data->tgid = pid_tgid >> 32;
48+
49+
// Get command name
50+
bpf_get_current_comm(&data->comm, sizeof(data->comm));
51+
52+
// Get timestamp
53+
data->timestamp = bpf_ktime_get_ns();
54+
55+
// Try to read sockaddr_in structure from userspace
56+
struct sockaddr_in addr;
57+
if (bpf_probe_read_user(&addr, sizeof(addr), (void *)sockaddr_ptr) == 0) {
58+
// Check if it's AF_INET (IPv4)
59+
if (addr.sin_family == AF_INET) {
60+
data->daddr = addr.sin_addr.s_addr;
61+
data->dport = __builtin_bswap16(addr.sin_port); // Convert from network byte order
62+
} else {
63+
// Not IPv4, discard
64+
bpf_ringbuf_discard(data, 0);
65+
return 0;
66+
}
67+
} else {
68+
// Failed to read sockaddr, set to 0
69+
data->daddr = 0;
70+
data->dport = 0;
71+
}
72+
73+
// Source address/port are harder to get from syscall, set to 0 for now
74+
data->saddr = 0;
75+
data->sport = 0;
76+
77+
// Submit data to userspace
78+
bpf_ringbuf_submit(data, 0);
79+
return 0;
80+
}
81+
82+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)