xref: /aosp_15_r20/external/bcc/libbpf-tools/tcptracer.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*387f9dfdSAndroid Build Coastguard Worker // Copyright (c) 2022 Microsoft Corporation
3*387f9dfdSAndroid Build Coastguard Worker //
4*387f9dfdSAndroid Build Coastguard Worker // Based on tcptracer(8) from BCC by Kinvolk GmbH and
5*387f9dfdSAndroid Build Coastguard Worker // tcpconnect(8) by Anton Protopopov
6*387f9dfdSAndroid Build Coastguard Worker #include <vmlinux.h>
7*387f9dfdSAndroid Build Coastguard Worker 
8*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_helpers.h>
9*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_core_read.h>
10*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_tracing.h>
11*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_endian.h>
12*387f9dfdSAndroid Build Coastguard Worker #include "tcptracer.h"
13*387f9dfdSAndroid Build Coastguard Worker 
14*387f9dfdSAndroid Build Coastguard Worker const volatile uid_t filter_uid = -1;
15*387f9dfdSAndroid Build Coastguard Worker const volatile pid_t filter_pid = 0;
16*387f9dfdSAndroid Build Coastguard Worker 
17*387f9dfdSAndroid Build Coastguard Worker /* Define here, because there are conflicts with include files */
18*387f9dfdSAndroid Build Coastguard Worker #define AF_INET		2
19*387f9dfdSAndroid Build Coastguard Worker #define AF_INET6	10
20*387f9dfdSAndroid Build Coastguard Worker 
21*387f9dfdSAndroid Build Coastguard Worker /*
22*387f9dfdSAndroid Build Coastguard Worker  * tcp_set_state doesn't run in the context of the process that initiated the
23*387f9dfdSAndroid Build Coastguard Worker  * connection so we need to store a map TUPLE -> PID to send the right PID on
24*387f9dfdSAndroid Build Coastguard Worker  * the event.
25*387f9dfdSAndroid Build Coastguard Worker  */
26*387f9dfdSAndroid Build Coastguard Worker struct tuple_key_t {
27*387f9dfdSAndroid Build Coastguard Worker 	union {
28*387f9dfdSAndroid Build Coastguard Worker 		__u32 saddr_v4;
29*387f9dfdSAndroid Build Coastguard Worker 		unsigned __int128 saddr_v6;
30*387f9dfdSAndroid Build Coastguard Worker 	};
31*387f9dfdSAndroid Build Coastguard Worker 	union {
32*387f9dfdSAndroid Build Coastguard Worker 		__u32 daddr_v4;
33*387f9dfdSAndroid Build Coastguard Worker 		unsigned __int128 daddr_v6;
34*387f9dfdSAndroid Build Coastguard Worker 	};
35*387f9dfdSAndroid Build Coastguard Worker 	u16 sport;
36*387f9dfdSAndroid Build Coastguard Worker 	u16 dport;
37*387f9dfdSAndroid Build Coastguard Worker 	u32 netns;
38*387f9dfdSAndroid Build Coastguard Worker };
39*387f9dfdSAndroid Build Coastguard Worker 
40*387f9dfdSAndroid Build Coastguard Worker struct pid_comm_t {
41*387f9dfdSAndroid Build Coastguard Worker 	u64 pid;
42*387f9dfdSAndroid Build Coastguard Worker 	char comm[TASK_COMM_LEN];
43*387f9dfdSAndroid Build Coastguard Worker 	u32 uid;
44*387f9dfdSAndroid Build Coastguard Worker };
45*387f9dfdSAndroid Build Coastguard Worker 
46*387f9dfdSAndroid Build Coastguard Worker struct {
47*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
48*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, MAX_ENTRIES);
49*387f9dfdSAndroid Build Coastguard Worker 	__type(key, struct tuple_key_t);
50*387f9dfdSAndroid Build Coastguard Worker 	__type(value, struct pid_comm_t);
51*387f9dfdSAndroid Build Coastguard Worker } tuplepid SEC(".maps");
52*387f9dfdSAndroid Build Coastguard Worker 
53*387f9dfdSAndroid Build Coastguard Worker struct {
54*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
55*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, MAX_ENTRIES);
56*387f9dfdSAndroid Build Coastguard Worker 	__type(key, u32);
57*387f9dfdSAndroid Build Coastguard Worker 	__type(value, struct sock *);
58*387f9dfdSAndroid Build Coastguard Worker } sockets SEC(".maps");
59*387f9dfdSAndroid Build Coastguard Worker 
60*387f9dfdSAndroid Build Coastguard Worker struct {
61*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
62*387f9dfdSAndroid Build Coastguard Worker 	__uint(key_size, sizeof(u32));
63*387f9dfdSAndroid Build Coastguard Worker 	__uint(value_size, sizeof(u32));
64*387f9dfdSAndroid Build Coastguard Worker } events SEC(".maps");
65*387f9dfdSAndroid Build Coastguard Worker 
66*387f9dfdSAndroid Build Coastguard Worker 
67*387f9dfdSAndroid Build Coastguard Worker static __always_inline bool
fill_tuple(struct tuple_key_t * tuple,struct sock * sk,int family)68*387f9dfdSAndroid Build Coastguard Worker fill_tuple(struct tuple_key_t *tuple, struct sock *sk, int family)
69*387f9dfdSAndroid Build Coastguard Worker {
70*387f9dfdSAndroid Build Coastguard Worker 	struct inet_sock *sockp = (struct inet_sock *)sk;
71*387f9dfdSAndroid Build Coastguard Worker 
72*387f9dfdSAndroid Build Coastguard Worker 	BPF_CORE_READ_INTO(&tuple->netns, sk, __sk_common.skc_net.net, ns.inum);
73*387f9dfdSAndroid Build Coastguard Worker 
74*387f9dfdSAndroid Build Coastguard Worker 	switch (family) {
75*387f9dfdSAndroid Build Coastguard Worker 	case AF_INET:
76*387f9dfdSAndroid Build Coastguard Worker 		BPF_CORE_READ_INTO(&tuple->saddr_v4, sk, __sk_common.skc_rcv_saddr);
77*387f9dfdSAndroid Build Coastguard Worker 		if (tuple->saddr_v4 == 0)
78*387f9dfdSAndroid Build Coastguard Worker 			return false;
79*387f9dfdSAndroid Build Coastguard Worker 
80*387f9dfdSAndroid Build Coastguard Worker 		BPF_CORE_READ_INTO(&tuple->daddr_v4, sk, __sk_common.skc_daddr);
81*387f9dfdSAndroid Build Coastguard Worker 		if (tuple->daddr_v4 == 0)
82*387f9dfdSAndroid Build Coastguard Worker 			return false;
83*387f9dfdSAndroid Build Coastguard Worker 
84*387f9dfdSAndroid Build Coastguard Worker 		break;
85*387f9dfdSAndroid Build Coastguard Worker 	case AF_INET6:
86*387f9dfdSAndroid Build Coastguard Worker 		BPF_CORE_READ_INTO(&tuple->saddr_v6, sk,
87*387f9dfdSAndroid Build Coastguard Worker 				   __sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
88*387f9dfdSAndroid Build Coastguard Worker 		if (tuple->saddr_v6 == 0)
89*387f9dfdSAndroid Build Coastguard Worker 			return false;
90*387f9dfdSAndroid Build Coastguard Worker 		BPF_CORE_READ_INTO(&tuple->daddr_v6, sk,
91*387f9dfdSAndroid Build Coastguard Worker 				   __sk_common.skc_v6_daddr.in6_u.u6_addr32);
92*387f9dfdSAndroid Build Coastguard Worker 		if (tuple->daddr_v6 == 0)
93*387f9dfdSAndroid Build Coastguard Worker 			return false;
94*387f9dfdSAndroid Build Coastguard Worker 
95*387f9dfdSAndroid Build Coastguard Worker 		break;
96*387f9dfdSAndroid Build Coastguard Worker 	/* it should not happen but to be sure let's handle this case */
97*387f9dfdSAndroid Build Coastguard Worker 	default:
98*387f9dfdSAndroid Build Coastguard Worker 		return false;
99*387f9dfdSAndroid Build Coastguard Worker 	}
100*387f9dfdSAndroid Build Coastguard Worker 
101*387f9dfdSAndroid Build Coastguard Worker 	BPF_CORE_READ_INTO(&tuple->dport, sk, __sk_common.skc_dport);
102*387f9dfdSAndroid Build Coastguard Worker 	if (tuple->dport == 0)
103*387f9dfdSAndroid Build Coastguard Worker 		return false;
104*387f9dfdSAndroid Build Coastguard Worker 
105*387f9dfdSAndroid Build Coastguard Worker 	BPF_CORE_READ_INTO(&tuple->sport, sockp, inet_sport);
106*387f9dfdSAndroid Build Coastguard Worker 	if (tuple->sport == 0)
107*387f9dfdSAndroid Build Coastguard Worker 		return false;
108*387f9dfdSAndroid Build Coastguard Worker 
109*387f9dfdSAndroid Build Coastguard Worker 	return true;
110*387f9dfdSAndroid Build Coastguard Worker }
111*387f9dfdSAndroid Build Coastguard Worker 
112*387f9dfdSAndroid Build Coastguard Worker static __always_inline void
fill_event(struct tuple_key_t * tuple,struct event * event,__u32 pid,__u32 uid,__u16 family,__u8 type)113*387f9dfdSAndroid Build Coastguard Worker fill_event(struct tuple_key_t *tuple, struct event *event, __u32 pid,
114*387f9dfdSAndroid Build Coastguard Worker 	   __u32 uid, __u16 family, __u8 type)
115*387f9dfdSAndroid Build Coastguard Worker {
116*387f9dfdSAndroid Build Coastguard Worker 	event->ts_us = bpf_ktime_get_ns() / 1000;
117*387f9dfdSAndroid Build Coastguard Worker 	event->type = type;
118*387f9dfdSAndroid Build Coastguard Worker 	event->pid = pid;
119*387f9dfdSAndroid Build Coastguard Worker 	event->uid = uid;
120*387f9dfdSAndroid Build Coastguard Worker 	event->af = family;
121*387f9dfdSAndroid Build Coastguard Worker 	event->netns = tuple->netns;
122*387f9dfdSAndroid Build Coastguard Worker 	if (family == AF_INET) {
123*387f9dfdSAndroid Build Coastguard Worker 		event->saddr_v4 = tuple->saddr_v4;
124*387f9dfdSAndroid Build Coastguard Worker 		event->daddr_v4 = tuple->daddr_v4;
125*387f9dfdSAndroid Build Coastguard Worker 	} else {
126*387f9dfdSAndroid Build Coastguard Worker 		event->saddr_v6 = tuple->saddr_v6;
127*387f9dfdSAndroid Build Coastguard Worker 		event->daddr_v6 = tuple->daddr_v6;
128*387f9dfdSAndroid Build Coastguard Worker 	}
129*387f9dfdSAndroid Build Coastguard Worker 	event->sport = tuple->sport;
130*387f9dfdSAndroid Build Coastguard Worker 	event->dport = tuple->dport;
131*387f9dfdSAndroid Build Coastguard Worker }
132*387f9dfdSAndroid Build Coastguard Worker 
133*387f9dfdSAndroid Build Coastguard Worker /* returns true if the event should be skipped */
134*387f9dfdSAndroid Build Coastguard Worker static __always_inline bool
filter_event(struct sock * sk,__u32 uid,__u32 pid)135*387f9dfdSAndroid Build Coastguard Worker filter_event(struct sock *sk, __u32 uid, __u32 pid)
136*387f9dfdSAndroid Build Coastguard Worker {
137*387f9dfdSAndroid Build Coastguard Worker 	u16 family = BPF_CORE_READ(sk, __sk_common.skc_family);
138*387f9dfdSAndroid Build Coastguard Worker 
139*387f9dfdSAndroid Build Coastguard Worker 	if (family != AF_INET && family != AF_INET6)
140*387f9dfdSAndroid Build Coastguard Worker 		return true;
141*387f9dfdSAndroid Build Coastguard Worker 
142*387f9dfdSAndroid Build Coastguard Worker 	if (filter_pid && pid != filter_pid)
143*387f9dfdSAndroid Build Coastguard Worker 		return true;
144*387f9dfdSAndroid Build Coastguard Worker 
145*387f9dfdSAndroid Build Coastguard Worker 	if (filter_uid != (uid_t) -1 && uid != filter_uid)
146*387f9dfdSAndroid Build Coastguard Worker 		return true;
147*387f9dfdSAndroid Build Coastguard Worker 
148*387f9dfdSAndroid Build Coastguard Worker 	return false;
149*387f9dfdSAndroid Build Coastguard Worker }
150*387f9dfdSAndroid Build Coastguard Worker 
151*387f9dfdSAndroid Build Coastguard Worker static __always_inline int
enter_tcp_connect(struct pt_regs * ctx,struct sock * sk)152*387f9dfdSAndroid Build Coastguard Worker enter_tcp_connect(struct pt_regs *ctx, struct sock *sk)
153*387f9dfdSAndroid Build Coastguard Worker {
154*387f9dfdSAndroid Build Coastguard Worker 	__u64 pid_tgid = bpf_get_current_pid_tgid();
155*387f9dfdSAndroid Build Coastguard Worker 	__u32 pid = pid_tgid >> 32;
156*387f9dfdSAndroid Build Coastguard Worker 	__u32 tid = pid_tgid;
157*387f9dfdSAndroid Build Coastguard Worker 	__u64 uid_gid = bpf_get_current_uid_gid();
158*387f9dfdSAndroid Build Coastguard Worker 	__u32 uid = uid_gid;
159*387f9dfdSAndroid Build Coastguard Worker 
160*387f9dfdSAndroid Build Coastguard Worker 	if (filter_event(sk, uid, pid))
161*387f9dfdSAndroid Build Coastguard Worker 		return 0;
162*387f9dfdSAndroid Build Coastguard Worker 
163*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_update_elem(&sockets, &tid, &sk, 0);
164*387f9dfdSAndroid Build Coastguard Worker 	return 0;
165*387f9dfdSAndroid Build Coastguard Worker }
166*387f9dfdSAndroid Build Coastguard Worker 
167*387f9dfdSAndroid Build Coastguard Worker static __always_inline int
exit_tcp_connect(struct pt_regs * ctx,int ret,__u16 family)168*387f9dfdSAndroid Build Coastguard Worker exit_tcp_connect(struct pt_regs *ctx, int ret, __u16 family)
169*387f9dfdSAndroid Build Coastguard Worker {
170*387f9dfdSAndroid Build Coastguard Worker 	__u64 pid_tgid = bpf_get_current_pid_tgid();
171*387f9dfdSAndroid Build Coastguard Worker 	__u32 pid = pid_tgid >> 32;
172*387f9dfdSAndroid Build Coastguard Worker 	__u32 tid = pid_tgid;
173*387f9dfdSAndroid Build Coastguard Worker 	__u64 uid_gid = bpf_get_current_uid_gid();
174*387f9dfdSAndroid Build Coastguard Worker 	__u32 uid = uid_gid;
175*387f9dfdSAndroid Build Coastguard Worker 	struct tuple_key_t tuple = {};
176*387f9dfdSAndroid Build Coastguard Worker 	struct pid_comm_t pid_comm = {};
177*387f9dfdSAndroid Build Coastguard Worker 	struct sock **skpp;
178*387f9dfdSAndroid Build Coastguard Worker 	struct sock *sk;
179*387f9dfdSAndroid Build Coastguard Worker 
180*387f9dfdSAndroid Build Coastguard Worker 	skpp = bpf_map_lookup_elem(&sockets, &tid);
181*387f9dfdSAndroid Build Coastguard Worker 	if (!skpp)
182*387f9dfdSAndroid Build Coastguard Worker 		return 0;
183*387f9dfdSAndroid Build Coastguard Worker 
184*387f9dfdSAndroid Build Coastguard Worker 	if (ret)
185*387f9dfdSAndroid Build Coastguard Worker 		goto end;
186*387f9dfdSAndroid Build Coastguard Worker 
187*387f9dfdSAndroid Build Coastguard Worker 	sk = *skpp;
188*387f9dfdSAndroid Build Coastguard Worker 
189*387f9dfdSAndroid Build Coastguard Worker 	if (!fill_tuple(&tuple, sk, family))
190*387f9dfdSAndroid Build Coastguard Worker 		goto end;
191*387f9dfdSAndroid Build Coastguard Worker 
192*387f9dfdSAndroid Build Coastguard Worker 	pid_comm.pid = pid;
193*387f9dfdSAndroid Build Coastguard Worker 	pid_comm.uid = uid;
194*387f9dfdSAndroid Build Coastguard Worker 	bpf_get_current_comm(&pid_comm.comm, sizeof(pid_comm.comm));
195*387f9dfdSAndroid Build Coastguard Worker 
196*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_update_elem(&tuplepid, &tuple, &pid_comm, 0);
197*387f9dfdSAndroid Build Coastguard Worker 
198*387f9dfdSAndroid Build Coastguard Worker end:
199*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&sockets, &tid);
200*387f9dfdSAndroid Build Coastguard Worker 	return 0;
201*387f9dfdSAndroid Build Coastguard Worker }
202*387f9dfdSAndroid Build Coastguard Worker 
203*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/tcp_v4_connect")
BPF_KPROBE(tcp_v4_connect,struct sock * sk)204*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(tcp_v4_connect, struct sock *sk)
205*387f9dfdSAndroid Build Coastguard Worker {
206*387f9dfdSAndroid Build Coastguard Worker 	return enter_tcp_connect(ctx, sk);
207*387f9dfdSAndroid Build Coastguard Worker }
208*387f9dfdSAndroid Build Coastguard Worker 
209*387f9dfdSAndroid Build Coastguard Worker SEC("kretprobe/tcp_v4_connect")
BPF_KRETPROBE(tcp_v4_connect_ret,int ret)210*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(tcp_v4_connect_ret, int ret)
211*387f9dfdSAndroid Build Coastguard Worker {
212*387f9dfdSAndroid Build Coastguard Worker 	return exit_tcp_connect(ctx, ret, AF_INET);
213*387f9dfdSAndroid Build Coastguard Worker }
214*387f9dfdSAndroid Build Coastguard Worker 
215*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/tcp_v6_connect")
BPF_KPROBE(tcp_v6_connect,struct sock * sk)216*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(tcp_v6_connect, struct sock *sk)
217*387f9dfdSAndroid Build Coastguard Worker {
218*387f9dfdSAndroid Build Coastguard Worker 	return enter_tcp_connect(ctx, sk);
219*387f9dfdSAndroid Build Coastguard Worker }
220*387f9dfdSAndroid Build Coastguard Worker 
221*387f9dfdSAndroid Build Coastguard Worker SEC("kretprobe/tcp_v6_connect")
BPF_KRETPROBE(tcp_v6_connect_ret,int ret)222*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(tcp_v6_connect_ret, int ret)
223*387f9dfdSAndroid Build Coastguard Worker {
224*387f9dfdSAndroid Build Coastguard Worker 	return exit_tcp_connect(ctx, ret, AF_INET6);
225*387f9dfdSAndroid Build Coastguard Worker }
226*387f9dfdSAndroid Build Coastguard Worker 
227*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/tcp_close")
BPF_KPROBE(entry_trace_close,struct sock * sk)228*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(entry_trace_close, struct sock *sk)
229*387f9dfdSAndroid Build Coastguard Worker {
230*387f9dfdSAndroid Build Coastguard Worker 	__u64 pid_tgid = bpf_get_current_pid_tgid();
231*387f9dfdSAndroid Build Coastguard Worker 	__u32 pid = pid_tgid >> 32;
232*387f9dfdSAndroid Build Coastguard Worker 	__u64 uid_gid = bpf_get_current_uid_gid();
233*387f9dfdSAndroid Build Coastguard Worker 	__u32 uid = uid_gid;
234*387f9dfdSAndroid Build Coastguard Worker 	struct tuple_key_t tuple = {};
235*387f9dfdSAndroid Build Coastguard Worker 	struct event event = {};
236*387f9dfdSAndroid Build Coastguard Worker 	u16 family;
237*387f9dfdSAndroid Build Coastguard Worker 
238*387f9dfdSAndroid Build Coastguard Worker 	if (filter_event(sk, uid, pid))
239*387f9dfdSAndroid Build Coastguard Worker 		return 0;
240*387f9dfdSAndroid Build Coastguard Worker 
241*387f9dfdSAndroid Build Coastguard Worker 	/*
242*387f9dfdSAndroid Build Coastguard Worker 	 * Don't generate close events for connections that were never
243*387f9dfdSAndroid Build Coastguard Worker 	 * established in the first place.
244*387f9dfdSAndroid Build Coastguard Worker 	 */
245*387f9dfdSAndroid Build Coastguard Worker 	u8 oldstate = BPF_CORE_READ(sk, __sk_common.skc_state);
246*387f9dfdSAndroid Build Coastguard Worker 	if (oldstate == TCP_SYN_SENT ||
247*387f9dfdSAndroid Build Coastguard Worker 	    oldstate == TCP_SYN_RECV ||
248*387f9dfdSAndroid Build Coastguard Worker 	    oldstate == TCP_NEW_SYN_RECV)
249*387f9dfdSAndroid Build Coastguard Worker 		return 0;
250*387f9dfdSAndroid Build Coastguard Worker 
251*387f9dfdSAndroid Build Coastguard Worker 	family = BPF_CORE_READ(sk, __sk_common.skc_family);
252*387f9dfdSAndroid Build Coastguard Worker 	if (!fill_tuple(&tuple, sk, family))
253*387f9dfdSAndroid Build Coastguard Worker 		return 0;
254*387f9dfdSAndroid Build Coastguard Worker 
255*387f9dfdSAndroid Build Coastguard Worker 	fill_event(&tuple, &event, pid, uid, family, TCP_EVENT_TYPE_CLOSE);
256*387f9dfdSAndroid Build Coastguard Worker 	bpf_get_current_comm(&event.task, sizeof(event.task));
257*387f9dfdSAndroid Build Coastguard Worker 
258*387f9dfdSAndroid Build Coastguard Worker 	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
259*387f9dfdSAndroid Build Coastguard Worker 		      &event, sizeof(event));
260*387f9dfdSAndroid Build Coastguard Worker 
261*387f9dfdSAndroid Build Coastguard Worker 	return 0;
262*387f9dfdSAndroid Build Coastguard Worker };
263*387f9dfdSAndroid Build Coastguard Worker 
264*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/tcp_set_state")
BPF_KPROBE(enter_tcp_set_state,struct sock * sk,int state)265*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(enter_tcp_set_state, struct sock *sk, int state)
266*387f9dfdSAndroid Build Coastguard Worker {
267*387f9dfdSAndroid Build Coastguard Worker 	struct tuple_key_t tuple = {};
268*387f9dfdSAndroid Build Coastguard Worker 	struct event event = {};
269*387f9dfdSAndroid Build Coastguard Worker 	__u16 family;
270*387f9dfdSAndroid Build Coastguard Worker 
271*387f9dfdSAndroid Build Coastguard Worker 	if (state != TCP_ESTABLISHED && state != TCP_CLOSE)
272*387f9dfdSAndroid Build Coastguard Worker 		goto end;
273*387f9dfdSAndroid Build Coastguard Worker 
274*387f9dfdSAndroid Build Coastguard Worker 	family = BPF_CORE_READ(sk, __sk_common.skc_family);
275*387f9dfdSAndroid Build Coastguard Worker 
276*387f9dfdSAndroid Build Coastguard Worker 	if (!fill_tuple(&tuple, sk, family))
277*387f9dfdSAndroid Build Coastguard Worker 		goto end;
278*387f9dfdSAndroid Build Coastguard Worker 
279*387f9dfdSAndroid Build Coastguard Worker 	if (state == TCP_CLOSE)
280*387f9dfdSAndroid Build Coastguard Worker 		goto end;
281*387f9dfdSAndroid Build Coastguard Worker 
282*387f9dfdSAndroid Build Coastguard Worker 	struct pid_comm_t *p;
283*387f9dfdSAndroid Build Coastguard Worker 	p = bpf_map_lookup_elem(&tuplepid, &tuple);
284*387f9dfdSAndroid Build Coastguard Worker 	if (!p)
285*387f9dfdSAndroid Build Coastguard Worker 		return 0; /* missed entry */
286*387f9dfdSAndroid Build Coastguard Worker 
287*387f9dfdSAndroid Build Coastguard Worker 	fill_event(&tuple, &event, p->pid, p->uid, family, TCP_EVENT_TYPE_CONNECT);
288*387f9dfdSAndroid Build Coastguard Worker 	__builtin_memcpy(&event.task, p->comm, sizeof(event.task));
289*387f9dfdSAndroid Build Coastguard Worker 
290*387f9dfdSAndroid Build Coastguard Worker 	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
291*387f9dfdSAndroid Build Coastguard Worker 			      &event, sizeof(event));
292*387f9dfdSAndroid Build Coastguard Worker 
293*387f9dfdSAndroid Build Coastguard Worker end:
294*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&tuplepid, &tuple);
295*387f9dfdSAndroid Build Coastguard Worker 
296*387f9dfdSAndroid Build Coastguard Worker 	return 0;
297*387f9dfdSAndroid Build Coastguard Worker }
298*387f9dfdSAndroid Build Coastguard Worker 
299*387f9dfdSAndroid Build Coastguard Worker SEC("kretprobe/inet_csk_accept")
BPF_KRETPROBE(exit_inet_csk_accept,struct sock * sk)300*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(exit_inet_csk_accept, struct sock *sk)
301*387f9dfdSAndroid Build Coastguard Worker {
302*387f9dfdSAndroid Build Coastguard Worker 	__u64 pid_tgid = bpf_get_current_pid_tgid();
303*387f9dfdSAndroid Build Coastguard Worker 	__u32 pid = pid_tgid >> 32;
304*387f9dfdSAndroid Build Coastguard Worker 	__u64 uid_gid = bpf_get_current_uid_gid();
305*387f9dfdSAndroid Build Coastguard Worker 	__u32 uid = uid_gid;
306*387f9dfdSAndroid Build Coastguard Worker 	__u16 sport, family;
307*387f9dfdSAndroid Build Coastguard Worker 	struct event event = {};
308*387f9dfdSAndroid Build Coastguard Worker 
309*387f9dfdSAndroid Build Coastguard Worker 	if (!sk)
310*387f9dfdSAndroid Build Coastguard Worker 		return 0;
311*387f9dfdSAndroid Build Coastguard Worker 
312*387f9dfdSAndroid Build Coastguard Worker 	if (filter_event(sk, uid, pid))
313*387f9dfdSAndroid Build Coastguard Worker 		return 0;
314*387f9dfdSAndroid Build Coastguard Worker 
315*387f9dfdSAndroid Build Coastguard Worker 	family = BPF_CORE_READ(sk, __sk_common.skc_family);
316*387f9dfdSAndroid Build Coastguard Worker 	sport = BPF_CORE_READ(sk, __sk_common.skc_num);
317*387f9dfdSAndroid Build Coastguard Worker 
318*387f9dfdSAndroid Build Coastguard Worker 	struct tuple_key_t t = {};
319*387f9dfdSAndroid Build Coastguard Worker 	fill_tuple(&t, sk, family);
320*387f9dfdSAndroid Build Coastguard Worker 	t.sport = bpf_ntohs(sport);
321*387f9dfdSAndroid Build Coastguard Worker 	/* do not send event if IP address is 0.0.0.0 or port is 0 */
322*387f9dfdSAndroid Build Coastguard Worker 	if (t.saddr_v6 == 0 || t.daddr_v6 == 0 || t.dport == 0 || t.sport == 0)
323*387f9dfdSAndroid Build Coastguard Worker 		return 0;
324*387f9dfdSAndroid Build Coastguard Worker 
325*387f9dfdSAndroid Build Coastguard Worker 	fill_event(&t, &event, pid, uid, family, TCP_EVENT_TYPE_ACCEPT);
326*387f9dfdSAndroid Build Coastguard Worker 
327*387f9dfdSAndroid Build Coastguard Worker 	bpf_get_current_comm(&event.task, sizeof(event.task));
328*387f9dfdSAndroid Build Coastguard Worker 	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
329*387f9dfdSAndroid Build Coastguard Worker 			      &event, sizeof(event));
330*387f9dfdSAndroid Build Coastguard Worker 
331*387f9dfdSAndroid Build Coastguard Worker 	return 0;
332*387f9dfdSAndroid Build Coastguard Worker }
333*387f9dfdSAndroid Build Coastguard Worker 
334*387f9dfdSAndroid Build Coastguard Worker 
335*387f9dfdSAndroid Build Coastguard Worker char LICENSE[] SEC("license") = "GPL";
336