-
Notifications
You must be signed in to change notification settings - Fork 75
/
Copy pathtcpreset.c
112 lines (98 loc) · 3 KB
/
tcpreset.c
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
102
103
104
105
106
107
108
109
110
111
112
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
// +build ignore
#include "vmlinux.h"
#include "bpf_helpers.h"
#include "bpf_core_read.h"
#include "bpf_tracing.h"
#include "inspector.h"
#define RESET_NOSOCK 1
#define RESET_ACTIVE 2
#define RESET_PROCESS 4
#define RESET_RECEIVE 8
struct receive_reset_args {
unsigned long pad;
const void * skaddr;
u16 sport;
u16 dport;
u8 saddr[4];
u8 daddr[4];
u8 saddr_v6[16];
u8 daddr_v6[16];
u64 sock_cookie;
}__attribute__((packed));
struct send_reset_args {
unsigned long pad;
const void * skbaddr;
const void * skaddr;
int state;
u16 sport;
u16 dport;
u8 saddr[4];
u8 daddr[4];
u8 saddr_v6[16];
u8 daddr_v6[16];
};
struct insp_tcpreset_event_t {
u32 type;
u8 state;
struct tuple tuple;
struct skb_meta skb_meta;
s64 stack_id;
};
struct insp_tcpreset_event_t *unused_event __attribute__((unused));
struct {
__uint(type, BPF_MAP_TYPE_STACK_TRACE);
__uint(max_entries, 1000);
__uint(key_size, sizeof(u32));
__uint(value_size, PERF_MAX_STACK_DEPTH * sizeof(u64));
} insp_tcpreset_stack SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
} insp_tcpreset_events SEC(".maps");
SEC("kprobe/tcp_v4_send_reset")
int trace_sendreset(struct pt_regs * ctx)
{
struct sock * sk = (struct sock *)PT_REGS_PARM1(ctx);
struct sk_buff * skb = (struct sk_buff *)(void *)PT_REGS_PARM2(ctx);
struct insp_tcpreset_event_t event = {0};
if (sk){
event.type = RESET_PROCESS;
}else{
event.type = RESET_NOSOCK;
}
bpf_core_read(&event.state,sizeof(event.state),&sk->__sk_common.skc_state);
event.stack_id = bpf_get_stackid((struct pt_regs *)ctx, &insp_tcpreset_stack, BPF_F_FAST_STACK_CMP);
set_tuple(skb, &event.tuple);
set_meta(skb,&event.skb_meta);
bpf_perf_event_output((struct pt_regs *)ctx,&insp_tcpreset_events,BPF_F_CURRENT_CPU,&event,sizeof(event));
return 0;
}
SEC("kprobe/tcp_send_active_reset")
int trace_sendactive(struct pt_regs * ctx)
{
struct sock * sk = (struct sock *)PT_REGS_PARM1(ctx);
struct insp_tcpreset_event_t event = {0};
event.type = RESET_ACTIVE;
bpf_core_read(&event.state,sizeof(event.state),&sk->__sk_common.skc_state);
set_tuple_sock(sk,&event.tuple);
set_meta_sock(sk,&event.skb_meta);
bpf_perf_event_output((struct pt_regs *)ctx,&insp_tcpreset_events,BPF_F_CURRENT_CPU,&event,sizeof(event));
return 0;
}
SEC("tracepoint/tcp/tcp_receive_reset")
int insp_rstrx(struct receive_reset_args *ctx)
{
struct insp_tcpreset_event_t event = {0};
event.stack_id = bpf_get_stackid((struct pt_regs *)ctx, &insp_tcpreset_stack, BPF_F_FAST_STACK_CMP);
if ((int)event.stack_id < 0) {
return 0;
}
event.type = RESET_RECEIVE;
struct sock * sk = (struct sock *)ctx->skaddr;
bpf_core_read(&event.state,sizeof(event.state),&sk->__sk_common.skc_state);
set_tuple_sock(sk,&event.tuple);
set_meta_sock(sk,&event.skb_meta);
bpf_perf_event_output((struct pt_regs *)ctx,&insp_tcpreset_events,BPF_F_CURRENT_CPU,&event,sizeof(event));
return 0;
}
char LICENSE[] SEC("license") = "Dual BSD/GPL";