-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathmain.go
101 lines (82 loc) · 2.16 KB
/
main.go
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
100
101
package main
import (
"bytes"
"context"
"encoding/binary"
"errors"
"log"
"net/netip"
"os"
"os/signal"
"syscall"
"github.com/cilium/ebpf"
"github.com/cilium/ebpf/link"
"github.com/cilium/ebpf/perf"
"github.com/cilium/ebpf/rlimit"
)
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang tcpconn ./ebpf/tcp-connecting.c -- -D__TARGET_ARCH_x86 -I../headers -Wall
func main() {
if err := rlimit.RemoveMemlock(); err != nil {
log.Fatalf("Failed to remove rlimit memlock: %v", err)
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
var obj tcpconnObjects
if err := loadTcpconnObjects(&obj, nil); err != nil {
log.Fatalf("Failed to load bpf obj: %v", err)
}
defer obj.Close()
if kp, err := link.Kprobe("tcp_connect", obj.K_tcpConnect, nil); err != nil {
log.Printf("Failed to attach kprobe(tcp_connect): %v", err)
return
} else {
defer kp.Close()
log.Printf("Attached kprobe(tcp_connect)")
}
if kp, err := link.Kprobe("inet_csk_complete_hashdance", obj.K_icskCompleteHashdance, nil); err != nil {
log.Printf("Failed to attach kprobe(inet_csk_complete_hashdance): %v", err)
return
} else {
defer kp.Close()
log.Printf("Attached kprobe(inet_csk_complete_hashdance)")
}
go handlePerfEvent(ctx, obj.Events)
<-ctx.Done()
}
func handlePerfEvent(ctx context.Context, events *ebpf.Map) {
eventReader, err := perf.NewReader(events, 4096)
if err != nil {
log.Printf("Failed to create perf-event reader: %v", err)
return
}
log.Printf("Listening events...")
go func() {
<-ctx.Done()
eventReader.Close()
}()
var ev struct {
Saddr, Daddr [4]byte
Sport, Dport uint16
}
for {
event, err := eventReader.Read()
if err != nil {
if errors.Is(err, perf.ErrClosed) {
return
}
log.Printf("Reading perf-event: %v", err)
}
if event.LostSamples != 0 {
log.Printf("Lost %d events", event.LostSamples)
}
binary.Read(bytes.NewBuffer(event.RawSample), binary.LittleEndian, &ev)
log.Printf("new tcp connection: %s:%d -> %s:%d",
netip.AddrFrom4(ev.Saddr), ev.Sport,
netip.AddrFrom4(ev.Daddr), ev.Dport)
select {
case <-ctx.Done():
return
default:
}
}
}