xref: /aosp_15_r20/external/bcc/tools/tcptracer.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python
2*387f9dfdSAndroid Build Coastguard Worker#
3*387f9dfdSAndroid Build Coastguard Worker# tcpv4tracer   Trace TCP connections.
4*387f9dfdSAndroid Build Coastguard Worker#               For Linux, uses BCC, eBPF. Embedded C.
5*387f9dfdSAndroid Build Coastguard Worker#
6*387f9dfdSAndroid Build Coastguard Worker# USAGE: tcpv4tracer [-h] [-v] [-p PID] [-N NETNS] [-4 | -6]
7*387f9dfdSAndroid Build Coastguard Worker#
8*387f9dfdSAndroid Build Coastguard Worker# You should generally try to avoid writing long scripts that measure multiple
9*387f9dfdSAndroid Build Coastguard Worker# functions and walk multiple kernel structures, as they will be a burden to
10*387f9dfdSAndroid Build Coastguard Worker# maintain as the kernel changes.
11*387f9dfdSAndroid Build Coastguard Worker# The following code should be replaced, and simplified, when static TCP probes
12*387f9dfdSAndroid Build Coastguard Worker# exist.
13*387f9dfdSAndroid Build Coastguard Worker#
14*387f9dfdSAndroid Build Coastguard Worker# Copyright 2017-2020 Kinvolk GmbH
15*387f9dfdSAndroid Build Coastguard Worker#
16*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
17*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
18*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
19*387f9dfdSAndroid Build Coastguard Workerfrom bcc.containers import filter_by_containers
20*387f9dfdSAndroid Build Coastguard Worker
21*387f9dfdSAndroid Build Coastguard Workerimport argparse as ap
22*387f9dfdSAndroid Build Coastguard Workerfrom socket import inet_ntop, AF_INET, AF_INET6
23*387f9dfdSAndroid Build Coastguard Workerfrom struct import pack
24*387f9dfdSAndroid Build Coastguard Worker
25*387f9dfdSAndroid Build Coastguard Workerparser = ap.ArgumentParser(description="Trace TCP connections",
26*387f9dfdSAndroid Build Coastguard Worker                           formatter_class=ap.RawDescriptionHelpFormatter)
27*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--timestamp", action="store_true",
28*387f9dfdSAndroid Build Coastguard Worker                    help="include timestamp on output")
29*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", default=0, type=int,
30*387f9dfdSAndroid Build Coastguard Worker                    help="trace this PID only")
31*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-N", "--netns", default=0, type=int,
32*387f9dfdSAndroid Build Coastguard Worker                    help="trace this Network Namespace only")
33*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--cgroupmap",
34*387f9dfdSAndroid Build Coastguard Worker                    help="trace cgroups in this BPF map only")
35*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--mntnsmap",
36*387f9dfdSAndroid Build Coastguard Worker                    help="trace mount namespaces in this BPF map only")
37*387f9dfdSAndroid Build Coastguard Workergroup = parser.add_mutually_exclusive_group()
38*387f9dfdSAndroid Build Coastguard Workergroup.add_argument("-4", "--ipv4", action="store_true",
39*387f9dfdSAndroid Build Coastguard Worker                    help="trace IPv4 family only")
40*387f9dfdSAndroid Build Coastguard Workergroup.add_argument("-6", "--ipv6", action="store_true",
41*387f9dfdSAndroid Build Coastguard Worker                   help="trace IPv6 family only")
42*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-v", "--verbose", action="store_true",
43*387f9dfdSAndroid Build Coastguard Worker                    help="include Network Namespace in the output")
44*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true",
45*387f9dfdSAndroid Build Coastguard Worker                    help=ap.SUPPRESS)
46*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
47*387f9dfdSAndroid Build Coastguard Worker
48*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
49*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
50*387f9dfdSAndroid Build Coastguard Worker#pragma clang diagnostic push
51*387f9dfdSAndroid Build Coastguard Worker#pragma clang diagnostic ignored "-Wtautological-compare"
52*387f9dfdSAndroid Build Coastguard Worker#include <net/sock.h>
53*387f9dfdSAndroid Build Coastguard Worker#pragma clang diagnostic pop
54*387f9dfdSAndroid Build Coastguard Worker#include <net/inet_sock.h>
55*387f9dfdSAndroid Build Coastguard Worker#include <net/net_namespace.h>
56*387f9dfdSAndroid Build Coastguard Worker#include <bcc/proto.h>
57*387f9dfdSAndroid Build Coastguard Worker
58*387f9dfdSAndroid Build Coastguard Worker#define TCP_EVENT_TYPE_CONNECT 1
59*387f9dfdSAndroid Build Coastguard Worker#define TCP_EVENT_TYPE_ACCEPT  2
60*387f9dfdSAndroid Build Coastguard Worker#define TCP_EVENT_TYPE_CLOSE   3
61*387f9dfdSAndroid Build Coastguard Worker
62*387f9dfdSAndroid Build Coastguard Workerstruct tcp_ipv4_event_t {
63*387f9dfdSAndroid Build Coastguard Worker    u64 ts_ns;
64*387f9dfdSAndroid Build Coastguard Worker    u32 type;
65*387f9dfdSAndroid Build Coastguard Worker    u32 pid;
66*387f9dfdSAndroid Build Coastguard Worker    char comm[TASK_COMM_LEN];
67*387f9dfdSAndroid Build Coastguard Worker    u8 ip;
68*387f9dfdSAndroid Build Coastguard Worker    u32 saddr;
69*387f9dfdSAndroid Build Coastguard Worker    u32 daddr;
70*387f9dfdSAndroid Build Coastguard Worker    u16 sport;
71*387f9dfdSAndroid Build Coastguard Worker    u16 dport;
72*387f9dfdSAndroid Build Coastguard Worker    u32 netns;
73*387f9dfdSAndroid Build Coastguard Worker};
74*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(tcp_ipv4_event);
75*387f9dfdSAndroid Build Coastguard Worker
76*387f9dfdSAndroid Build Coastguard Workerstruct tcp_ipv6_event_t {
77*387f9dfdSAndroid Build Coastguard Worker    u64 ts_ns;
78*387f9dfdSAndroid Build Coastguard Worker    u32 type;
79*387f9dfdSAndroid Build Coastguard Worker    u32 pid;
80*387f9dfdSAndroid Build Coastguard Worker    char comm[TASK_COMM_LEN];
81*387f9dfdSAndroid Build Coastguard Worker    unsigned __int128 saddr;
82*387f9dfdSAndroid Build Coastguard Worker    unsigned __int128 daddr;
83*387f9dfdSAndroid Build Coastguard Worker    u16 sport;
84*387f9dfdSAndroid Build Coastguard Worker    u16 dport;
85*387f9dfdSAndroid Build Coastguard Worker    u32 netns;
86*387f9dfdSAndroid Build Coastguard Worker    u8 ip;
87*387f9dfdSAndroid Build Coastguard Worker};
88*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(tcp_ipv6_event);
89*387f9dfdSAndroid Build Coastguard Worker
90*387f9dfdSAndroid Build Coastguard Worker// tcp_set_state doesn't run in the context of the process that initiated the
91*387f9dfdSAndroid Build Coastguard Worker// connection so we need to store a map TUPLE -> PID to send the right PID on
92*387f9dfdSAndroid Build Coastguard Worker// the event
93*387f9dfdSAndroid Build Coastguard Workerstruct ipv4_tuple_t {
94*387f9dfdSAndroid Build Coastguard Worker    u32 saddr;
95*387f9dfdSAndroid Build Coastguard Worker    u32 daddr;
96*387f9dfdSAndroid Build Coastguard Worker    u16 sport;
97*387f9dfdSAndroid Build Coastguard Worker    u16 dport;
98*387f9dfdSAndroid Build Coastguard Worker    u32 netns;
99*387f9dfdSAndroid Build Coastguard Worker};
100*387f9dfdSAndroid Build Coastguard Worker
101*387f9dfdSAndroid Build Coastguard Workerstruct ipv6_tuple_t {
102*387f9dfdSAndroid Build Coastguard Worker    unsigned __int128 saddr;
103*387f9dfdSAndroid Build Coastguard Worker    unsigned __int128 daddr;
104*387f9dfdSAndroid Build Coastguard Worker    u16 sport;
105*387f9dfdSAndroid Build Coastguard Worker    u16 dport;
106*387f9dfdSAndroid Build Coastguard Worker    u32 netns;
107*387f9dfdSAndroid Build Coastguard Worker};
108*387f9dfdSAndroid Build Coastguard Worker
109*387f9dfdSAndroid Build Coastguard Workerstruct pid_comm_t {
110*387f9dfdSAndroid Build Coastguard Worker    u64 pid;
111*387f9dfdSAndroid Build Coastguard Worker    char comm[TASK_COMM_LEN];
112*387f9dfdSAndroid Build Coastguard Worker};
113*387f9dfdSAndroid Build Coastguard Worker
114*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(tuplepid_ipv4, struct ipv4_tuple_t, struct pid_comm_t);
115*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(tuplepid_ipv6, struct ipv6_tuple_t, struct pid_comm_t);
116*387f9dfdSAndroid Build Coastguard Worker
117*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(connectsock, u64, struct sock *);
118*387f9dfdSAndroid Build Coastguard Worker
119*387f9dfdSAndroid Build Coastguard Workerstatic int read_ipv4_tuple(struct ipv4_tuple_t *tuple, struct sock *skp)
120*387f9dfdSAndroid Build Coastguard Worker{
121*387f9dfdSAndroid Build Coastguard Worker  u32 net_ns_inum = 0;
122*387f9dfdSAndroid Build Coastguard Worker  u32 saddr = skp->__sk_common.skc_rcv_saddr;
123*387f9dfdSAndroid Build Coastguard Worker  u32 daddr = skp->__sk_common.skc_daddr;
124*387f9dfdSAndroid Build Coastguard Worker  struct inet_sock *sockp = (struct inet_sock *)skp;
125*387f9dfdSAndroid Build Coastguard Worker  u16 sport = sockp->inet_sport;
126*387f9dfdSAndroid Build Coastguard Worker  u16 dport = skp->__sk_common.skc_dport;
127*387f9dfdSAndroid Build Coastguard Worker#ifdef CONFIG_NET_NS
128*387f9dfdSAndroid Build Coastguard Worker  net_ns_inum = skp->__sk_common.skc_net.net->ns.inum;
129*387f9dfdSAndroid Build Coastguard Worker#endif
130*387f9dfdSAndroid Build Coastguard Worker
131*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_NETNS##
132*387f9dfdSAndroid Build Coastguard Worker
133*387f9dfdSAndroid Build Coastguard Worker  tuple->saddr = saddr;
134*387f9dfdSAndroid Build Coastguard Worker  tuple->daddr = daddr;
135*387f9dfdSAndroid Build Coastguard Worker  tuple->sport = sport;
136*387f9dfdSAndroid Build Coastguard Worker  tuple->dport = dport;
137*387f9dfdSAndroid Build Coastguard Worker  tuple->netns = net_ns_inum;
138*387f9dfdSAndroid Build Coastguard Worker
139*387f9dfdSAndroid Build Coastguard Worker  // if addresses or ports are 0, ignore
140*387f9dfdSAndroid Build Coastguard Worker  if (saddr == 0 || daddr == 0 || sport == 0 || dport == 0) {
141*387f9dfdSAndroid Build Coastguard Worker      return 0;
142*387f9dfdSAndroid Build Coastguard Worker  }
143*387f9dfdSAndroid Build Coastguard Worker
144*387f9dfdSAndroid Build Coastguard Worker  return 1;
145*387f9dfdSAndroid Build Coastguard Worker}
146*387f9dfdSAndroid Build Coastguard Worker
147*387f9dfdSAndroid Build Coastguard Workerstatic int read_ipv6_tuple(struct ipv6_tuple_t *tuple, struct sock *skp)
148*387f9dfdSAndroid Build Coastguard Worker{
149*387f9dfdSAndroid Build Coastguard Worker  u32 net_ns_inum = 0;
150*387f9dfdSAndroid Build Coastguard Worker  unsigned __int128 saddr = 0, daddr = 0;
151*387f9dfdSAndroid Build Coastguard Worker  struct inet_sock *sockp = (struct inet_sock *)skp;
152*387f9dfdSAndroid Build Coastguard Worker  u16 sport = sockp->inet_sport;
153*387f9dfdSAndroid Build Coastguard Worker  u16 dport = skp->__sk_common.skc_dport;
154*387f9dfdSAndroid Build Coastguard Worker#ifdef CONFIG_NET_NS
155*387f9dfdSAndroid Build Coastguard Worker  net_ns_inum = skp->__sk_common.skc_net.net->ns.inum;
156*387f9dfdSAndroid Build Coastguard Worker#endif
157*387f9dfdSAndroid Build Coastguard Worker  bpf_probe_read_kernel(&saddr, sizeof(saddr),
158*387f9dfdSAndroid Build Coastguard Worker                 skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
159*387f9dfdSAndroid Build Coastguard Worker  bpf_probe_read_kernel(&daddr, sizeof(daddr),
160*387f9dfdSAndroid Build Coastguard Worker                 skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
161*387f9dfdSAndroid Build Coastguard Worker
162*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_NETNS##
163*387f9dfdSAndroid Build Coastguard Worker
164*387f9dfdSAndroid Build Coastguard Worker  tuple->saddr = saddr;
165*387f9dfdSAndroid Build Coastguard Worker  tuple->daddr = daddr;
166*387f9dfdSAndroid Build Coastguard Worker  tuple->sport = sport;
167*387f9dfdSAndroid Build Coastguard Worker  tuple->dport = dport;
168*387f9dfdSAndroid Build Coastguard Worker  tuple->netns = net_ns_inum;
169*387f9dfdSAndroid Build Coastguard Worker
170*387f9dfdSAndroid Build Coastguard Worker  // if addresses or ports are 0, ignore
171*387f9dfdSAndroid Build Coastguard Worker  if (saddr == 0 || daddr == 0 || sport == 0 || dport == 0) {
172*387f9dfdSAndroid Build Coastguard Worker      return 0;
173*387f9dfdSAndroid Build Coastguard Worker  }
174*387f9dfdSAndroid Build Coastguard Worker
175*387f9dfdSAndroid Build Coastguard Worker  return 1;
176*387f9dfdSAndroid Build Coastguard Worker}
177*387f9dfdSAndroid Build Coastguard Worker
178*387f9dfdSAndroid Build Coastguard Workerstatic bool check_family(struct sock *sk, u16 expected_family) {
179*387f9dfdSAndroid Build Coastguard Worker  u64 zero = 0;
180*387f9dfdSAndroid Build Coastguard Worker  u16 family = sk->__sk_common.skc_family;
181*387f9dfdSAndroid Build Coastguard Worker  return family == expected_family;
182*387f9dfdSAndroid Build Coastguard Worker}
183*387f9dfdSAndroid Build Coastguard Worker
184*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v4_entry(struct pt_regs *ctx, struct sock *sk)
185*387f9dfdSAndroid Build Coastguard Worker{
186*387f9dfdSAndroid Build Coastguard Worker  if (container_should_be_filtered()) {
187*387f9dfdSAndroid Build Coastguard Worker    return 0;
188*387f9dfdSAndroid Build Coastguard Worker  }
189*387f9dfdSAndroid Build Coastguard Worker
190*387f9dfdSAndroid Build Coastguard Worker  u64 pid = bpf_get_current_pid_tgid();
191*387f9dfdSAndroid Build Coastguard Worker
192*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_PID##
193*387f9dfdSAndroid Build Coastguard Worker
194*387f9dfdSAndroid Build Coastguard Worker  u16 family = sk->__sk_common.skc_family;
195*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_FAMILY##
196*387f9dfdSAndroid Build Coastguard Worker
197*387f9dfdSAndroid Build Coastguard Worker
198*387f9dfdSAndroid Build Coastguard Worker  // stash the sock ptr for lookup on return
199*387f9dfdSAndroid Build Coastguard Worker  connectsock.update(&pid, &sk);
200*387f9dfdSAndroid Build Coastguard Worker
201*387f9dfdSAndroid Build Coastguard Worker  return 0;
202*387f9dfdSAndroid Build Coastguard Worker}
203*387f9dfdSAndroid Build Coastguard Worker
204*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v4_return(struct pt_regs *ctx)
205*387f9dfdSAndroid Build Coastguard Worker{
206*387f9dfdSAndroid Build Coastguard Worker  int ret = PT_REGS_RC(ctx);
207*387f9dfdSAndroid Build Coastguard Worker  u64 pid = bpf_get_current_pid_tgid();
208*387f9dfdSAndroid Build Coastguard Worker
209*387f9dfdSAndroid Build Coastguard Worker  struct sock **skpp;
210*387f9dfdSAndroid Build Coastguard Worker  skpp = connectsock.lookup(&pid);
211*387f9dfdSAndroid Build Coastguard Worker  if (skpp == 0) {
212*387f9dfdSAndroid Build Coastguard Worker      return 0;       // missed entry
213*387f9dfdSAndroid Build Coastguard Worker  }
214*387f9dfdSAndroid Build Coastguard Worker
215*387f9dfdSAndroid Build Coastguard Worker  connectsock.delete(&pid);
216*387f9dfdSAndroid Build Coastguard Worker
217*387f9dfdSAndroid Build Coastguard Worker  if (ret != 0) {
218*387f9dfdSAndroid Build Coastguard Worker      // failed to send SYNC packet, may not have populated
219*387f9dfdSAndroid Build Coastguard Worker      // socket __sk_common.{skc_rcv_saddr, ...}
220*387f9dfdSAndroid Build Coastguard Worker      return 0;
221*387f9dfdSAndroid Build Coastguard Worker  }
222*387f9dfdSAndroid Build Coastguard Worker
223*387f9dfdSAndroid Build Coastguard Worker  // pull in details
224*387f9dfdSAndroid Build Coastguard Worker  struct sock *skp = *skpp;
225*387f9dfdSAndroid Build Coastguard Worker  struct ipv4_tuple_t t = { };
226*387f9dfdSAndroid Build Coastguard Worker  if (!read_ipv4_tuple(&t, skp)) {
227*387f9dfdSAndroid Build Coastguard Worker      return 0;
228*387f9dfdSAndroid Build Coastguard Worker  }
229*387f9dfdSAndroid Build Coastguard Worker
230*387f9dfdSAndroid Build Coastguard Worker  struct pid_comm_t p = { };
231*387f9dfdSAndroid Build Coastguard Worker  p.pid = pid;
232*387f9dfdSAndroid Build Coastguard Worker  bpf_get_current_comm(&p.comm, sizeof(p.comm));
233*387f9dfdSAndroid Build Coastguard Worker
234*387f9dfdSAndroid Build Coastguard Worker  tuplepid_ipv4.update(&t, &p);
235*387f9dfdSAndroid Build Coastguard Worker
236*387f9dfdSAndroid Build Coastguard Worker  return 0;
237*387f9dfdSAndroid Build Coastguard Worker}
238*387f9dfdSAndroid Build Coastguard Worker
239*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v6_entry(struct pt_regs *ctx, struct sock *sk)
240*387f9dfdSAndroid Build Coastguard Worker{
241*387f9dfdSAndroid Build Coastguard Worker  if (container_should_be_filtered()) {
242*387f9dfdSAndroid Build Coastguard Worker    return 0;
243*387f9dfdSAndroid Build Coastguard Worker  }
244*387f9dfdSAndroid Build Coastguard Worker  u64 pid = bpf_get_current_pid_tgid();
245*387f9dfdSAndroid Build Coastguard Worker
246*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_PID##
247*387f9dfdSAndroid Build Coastguard Worker  u16 family = sk->__sk_common.skc_family;
248*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_FAMILY##
249*387f9dfdSAndroid Build Coastguard Worker
250*387f9dfdSAndroid Build Coastguard Worker  // stash the sock ptr for lookup on return
251*387f9dfdSAndroid Build Coastguard Worker  connectsock.update(&pid, &sk);
252*387f9dfdSAndroid Build Coastguard Worker
253*387f9dfdSAndroid Build Coastguard Worker  return 0;
254*387f9dfdSAndroid Build Coastguard Worker}
255*387f9dfdSAndroid Build Coastguard Worker
256*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v6_return(struct pt_regs *ctx)
257*387f9dfdSAndroid Build Coastguard Worker{
258*387f9dfdSAndroid Build Coastguard Worker  int ret = PT_REGS_RC(ctx);
259*387f9dfdSAndroid Build Coastguard Worker  u64 pid = bpf_get_current_pid_tgid();
260*387f9dfdSAndroid Build Coastguard Worker
261*387f9dfdSAndroid Build Coastguard Worker  struct sock **skpp;
262*387f9dfdSAndroid Build Coastguard Worker  skpp = connectsock.lookup(&pid);
263*387f9dfdSAndroid Build Coastguard Worker  if (skpp == 0) {
264*387f9dfdSAndroid Build Coastguard Worker      return 0;       // missed entry
265*387f9dfdSAndroid Build Coastguard Worker  }
266*387f9dfdSAndroid Build Coastguard Worker
267*387f9dfdSAndroid Build Coastguard Worker  connectsock.delete(&pid);
268*387f9dfdSAndroid Build Coastguard Worker
269*387f9dfdSAndroid Build Coastguard Worker  if (ret != 0) {
270*387f9dfdSAndroid Build Coastguard Worker      // failed to send SYNC packet, may not have populated
271*387f9dfdSAndroid Build Coastguard Worker      // socket __sk_common.{skc_rcv_saddr, ...}
272*387f9dfdSAndroid Build Coastguard Worker      return 0;
273*387f9dfdSAndroid Build Coastguard Worker  }
274*387f9dfdSAndroid Build Coastguard Worker
275*387f9dfdSAndroid Build Coastguard Worker  // pull in details
276*387f9dfdSAndroid Build Coastguard Worker  struct sock *skp = *skpp;
277*387f9dfdSAndroid Build Coastguard Worker  struct ipv6_tuple_t t = { };
278*387f9dfdSAndroid Build Coastguard Worker  if (!read_ipv6_tuple(&t, skp)) {
279*387f9dfdSAndroid Build Coastguard Worker      return 0;
280*387f9dfdSAndroid Build Coastguard Worker  }
281*387f9dfdSAndroid Build Coastguard Worker
282*387f9dfdSAndroid Build Coastguard Worker  struct pid_comm_t p = { };
283*387f9dfdSAndroid Build Coastguard Worker  p.pid = pid;
284*387f9dfdSAndroid Build Coastguard Worker  bpf_get_current_comm(&p.comm, sizeof(p.comm));
285*387f9dfdSAndroid Build Coastguard Worker
286*387f9dfdSAndroid Build Coastguard Worker  tuplepid_ipv6.update(&t, &p);
287*387f9dfdSAndroid Build Coastguard Worker
288*387f9dfdSAndroid Build Coastguard Worker  return 0;
289*387f9dfdSAndroid Build Coastguard Worker}
290*387f9dfdSAndroid Build Coastguard Worker
291*387f9dfdSAndroid Build Coastguard Workerint trace_tcp_set_state_entry(struct pt_regs *ctx, struct sock *skp, int state)
292*387f9dfdSAndroid Build Coastguard Worker{
293*387f9dfdSAndroid Build Coastguard Worker  if (state != TCP_ESTABLISHED && state != TCP_CLOSE) {
294*387f9dfdSAndroid Build Coastguard Worker      return 0;
295*387f9dfdSAndroid Build Coastguard Worker  }
296*387f9dfdSAndroid Build Coastguard Worker
297*387f9dfdSAndroid Build Coastguard Worker  u16 family = skp->__sk_common.skc_family;
298*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_FAMILY##
299*387f9dfdSAndroid Build Coastguard Worker
300*387f9dfdSAndroid Build Coastguard Worker  u8 ipver = 0;
301*387f9dfdSAndroid Build Coastguard Worker  if (check_family(skp, AF_INET)) {
302*387f9dfdSAndroid Build Coastguard Worker      ipver = 4;
303*387f9dfdSAndroid Build Coastguard Worker      struct ipv4_tuple_t t = { };
304*387f9dfdSAndroid Build Coastguard Worker      if (!read_ipv4_tuple(&t, skp)) {
305*387f9dfdSAndroid Build Coastguard Worker          return 0;
306*387f9dfdSAndroid Build Coastguard Worker      }
307*387f9dfdSAndroid Build Coastguard Worker
308*387f9dfdSAndroid Build Coastguard Worker      if (state == TCP_CLOSE) {
309*387f9dfdSAndroid Build Coastguard Worker          tuplepid_ipv4.delete(&t);
310*387f9dfdSAndroid Build Coastguard Worker          return 0;
311*387f9dfdSAndroid Build Coastguard Worker      }
312*387f9dfdSAndroid Build Coastguard Worker
313*387f9dfdSAndroid Build Coastguard Worker      struct pid_comm_t *p;
314*387f9dfdSAndroid Build Coastguard Worker      p = tuplepid_ipv4.lookup(&t);
315*387f9dfdSAndroid Build Coastguard Worker      if (p == 0) {
316*387f9dfdSAndroid Build Coastguard Worker          return 0;       // missed entry
317*387f9dfdSAndroid Build Coastguard Worker      }
318*387f9dfdSAndroid Build Coastguard Worker
319*387f9dfdSAndroid Build Coastguard Worker      struct tcp_ipv4_event_t evt4 = { };
320*387f9dfdSAndroid Build Coastguard Worker      evt4.ts_ns = bpf_ktime_get_ns();
321*387f9dfdSAndroid Build Coastguard Worker      evt4.type = TCP_EVENT_TYPE_CONNECT;
322*387f9dfdSAndroid Build Coastguard Worker      evt4.pid = p->pid >> 32;
323*387f9dfdSAndroid Build Coastguard Worker      evt4.ip = ipver;
324*387f9dfdSAndroid Build Coastguard Worker      evt4.saddr = t.saddr;
325*387f9dfdSAndroid Build Coastguard Worker      evt4.daddr = t.daddr;
326*387f9dfdSAndroid Build Coastguard Worker      evt4.sport = ntohs(t.sport);
327*387f9dfdSAndroid Build Coastguard Worker      evt4.dport = ntohs(t.dport);
328*387f9dfdSAndroid Build Coastguard Worker      evt4.netns = t.netns;
329*387f9dfdSAndroid Build Coastguard Worker
330*387f9dfdSAndroid Build Coastguard Worker      int i;
331*387f9dfdSAndroid Build Coastguard Worker      for (i = 0; i < TASK_COMM_LEN; i++) {
332*387f9dfdSAndroid Build Coastguard Worker          evt4.comm[i] = p->comm[i];
333*387f9dfdSAndroid Build Coastguard Worker      }
334*387f9dfdSAndroid Build Coastguard Worker
335*387f9dfdSAndroid Build Coastguard Worker      tcp_ipv4_event.perf_submit(ctx, &evt4, sizeof(evt4));
336*387f9dfdSAndroid Build Coastguard Worker      tuplepid_ipv4.delete(&t);
337*387f9dfdSAndroid Build Coastguard Worker  } else if (check_family(skp, AF_INET6)) {
338*387f9dfdSAndroid Build Coastguard Worker      ipver = 6;
339*387f9dfdSAndroid Build Coastguard Worker      struct ipv6_tuple_t t = { };
340*387f9dfdSAndroid Build Coastguard Worker      if (!read_ipv6_tuple(&t, skp)) {
341*387f9dfdSAndroid Build Coastguard Worker          return 0;
342*387f9dfdSAndroid Build Coastguard Worker      }
343*387f9dfdSAndroid Build Coastguard Worker
344*387f9dfdSAndroid Build Coastguard Worker      if (state == TCP_CLOSE) {
345*387f9dfdSAndroid Build Coastguard Worker          tuplepid_ipv6.delete(&t);
346*387f9dfdSAndroid Build Coastguard Worker          return 0;
347*387f9dfdSAndroid Build Coastguard Worker      }
348*387f9dfdSAndroid Build Coastguard Worker
349*387f9dfdSAndroid Build Coastguard Worker      struct pid_comm_t *p;
350*387f9dfdSAndroid Build Coastguard Worker      p = tuplepid_ipv6.lookup(&t);
351*387f9dfdSAndroid Build Coastguard Worker      if (p == 0) {
352*387f9dfdSAndroid Build Coastguard Worker          return 0;       // missed entry
353*387f9dfdSAndroid Build Coastguard Worker      }
354*387f9dfdSAndroid Build Coastguard Worker
355*387f9dfdSAndroid Build Coastguard Worker      struct tcp_ipv6_event_t evt6 = { };
356*387f9dfdSAndroid Build Coastguard Worker      evt6.ts_ns = bpf_ktime_get_ns();
357*387f9dfdSAndroid Build Coastguard Worker      evt6.type = TCP_EVENT_TYPE_CONNECT;
358*387f9dfdSAndroid Build Coastguard Worker      evt6.pid = p->pid >> 32;
359*387f9dfdSAndroid Build Coastguard Worker      evt6.ip = ipver;
360*387f9dfdSAndroid Build Coastguard Worker      evt6.saddr = t.saddr;
361*387f9dfdSAndroid Build Coastguard Worker      evt6.daddr = t.daddr;
362*387f9dfdSAndroid Build Coastguard Worker      evt6.sport = ntohs(t.sport);
363*387f9dfdSAndroid Build Coastguard Worker      evt6.dport = ntohs(t.dport);
364*387f9dfdSAndroid Build Coastguard Worker      evt6.netns = t.netns;
365*387f9dfdSAndroid Build Coastguard Worker
366*387f9dfdSAndroid Build Coastguard Worker      int i;
367*387f9dfdSAndroid Build Coastguard Worker      for (i = 0; i < TASK_COMM_LEN; i++) {
368*387f9dfdSAndroid Build Coastguard Worker          evt6.comm[i] = p->comm[i];
369*387f9dfdSAndroid Build Coastguard Worker      }
370*387f9dfdSAndroid Build Coastguard Worker
371*387f9dfdSAndroid Build Coastguard Worker      tcp_ipv6_event.perf_submit(ctx, &evt6, sizeof(evt6));
372*387f9dfdSAndroid Build Coastguard Worker      tuplepid_ipv6.delete(&t);
373*387f9dfdSAndroid Build Coastguard Worker  }
374*387f9dfdSAndroid Build Coastguard Worker  // else drop
375*387f9dfdSAndroid Build Coastguard Worker
376*387f9dfdSAndroid Build Coastguard Worker  return 0;
377*387f9dfdSAndroid Build Coastguard Worker}
378*387f9dfdSAndroid Build Coastguard Worker
379*387f9dfdSAndroid Build Coastguard Workerint trace_close_entry(struct pt_regs *ctx, struct sock *skp)
380*387f9dfdSAndroid Build Coastguard Worker{
381*387f9dfdSAndroid Build Coastguard Worker  if (container_should_be_filtered()) {
382*387f9dfdSAndroid Build Coastguard Worker    return 0;
383*387f9dfdSAndroid Build Coastguard Worker  }
384*387f9dfdSAndroid Build Coastguard Worker
385*387f9dfdSAndroid Build Coastguard Worker  u64 pid = bpf_get_current_pid_tgid();
386*387f9dfdSAndroid Build Coastguard Worker
387*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_PID##
388*387f9dfdSAndroid Build Coastguard Worker
389*387f9dfdSAndroid Build Coastguard Worker  u16 family = skp->__sk_common.skc_family;
390*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_FAMILY##
391*387f9dfdSAndroid Build Coastguard Worker
392*387f9dfdSAndroid Build Coastguard Worker  u8 oldstate = skp->sk_state;
393*387f9dfdSAndroid Build Coastguard Worker  // Don't generate close events for connections that were never
394*387f9dfdSAndroid Build Coastguard Worker  // established in the first place.
395*387f9dfdSAndroid Build Coastguard Worker  if (oldstate == TCP_SYN_SENT ||
396*387f9dfdSAndroid Build Coastguard Worker      oldstate == TCP_SYN_RECV ||
397*387f9dfdSAndroid Build Coastguard Worker      oldstate == TCP_NEW_SYN_RECV)
398*387f9dfdSAndroid Build Coastguard Worker      return 0;
399*387f9dfdSAndroid Build Coastguard Worker
400*387f9dfdSAndroid Build Coastguard Worker  u8 ipver = 0;
401*387f9dfdSAndroid Build Coastguard Worker  if (check_family(skp, AF_INET)) {
402*387f9dfdSAndroid Build Coastguard Worker      ipver = 4;
403*387f9dfdSAndroid Build Coastguard Worker      struct ipv4_tuple_t t = { };
404*387f9dfdSAndroid Build Coastguard Worker      if (!read_ipv4_tuple(&t, skp)) {
405*387f9dfdSAndroid Build Coastguard Worker          return 0;
406*387f9dfdSAndroid Build Coastguard Worker      }
407*387f9dfdSAndroid Build Coastguard Worker
408*387f9dfdSAndroid Build Coastguard Worker      struct tcp_ipv4_event_t evt4 = { };
409*387f9dfdSAndroid Build Coastguard Worker      evt4.ts_ns = bpf_ktime_get_ns();
410*387f9dfdSAndroid Build Coastguard Worker      evt4.type = TCP_EVENT_TYPE_CLOSE;
411*387f9dfdSAndroid Build Coastguard Worker      evt4.pid = pid >> 32;
412*387f9dfdSAndroid Build Coastguard Worker      evt4.ip = ipver;
413*387f9dfdSAndroid Build Coastguard Worker      evt4.saddr = t.saddr;
414*387f9dfdSAndroid Build Coastguard Worker      evt4.daddr = t.daddr;
415*387f9dfdSAndroid Build Coastguard Worker      evt4.sport = ntohs(t.sport);
416*387f9dfdSAndroid Build Coastguard Worker      evt4.dport = ntohs(t.dport);
417*387f9dfdSAndroid Build Coastguard Worker      evt4.netns = t.netns;
418*387f9dfdSAndroid Build Coastguard Worker      bpf_get_current_comm(&evt4.comm, sizeof(evt4.comm));
419*387f9dfdSAndroid Build Coastguard Worker
420*387f9dfdSAndroid Build Coastguard Worker      tcp_ipv4_event.perf_submit(ctx, &evt4, sizeof(evt4));
421*387f9dfdSAndroid Build Coastguard Worker  } else if (check_family(skp, AF_INET6)) {
422*387f9dfdSAndroid Build Coastguard Worker      ipver = 6;
423*387f9dfdSAndroid Build Coastguard Worker      struct ipv6_tuple_t t = { };
424*387f9dfdSAndroid Build Coastguard Worker      if (!read_ipv6_tuple(&t, skp)) {
425*387f9dfdSAndroid Build Coastguard Worker          return 0;
426*387f9dfdSAndroid Build Coastguard Worker      }
427*387f9dfdSAndroid Build Coastguard Worker
428*387f9dfdSAndroid Build Coastguard Worker      struct tcp_ipv6_event_t evt6 = { };
429*387f9dfdSAndroid Build Coastguard Worker      evt6.ts_ns = bpf_ktime_get_ns();
430*387f9dfdSAndroid Build Coastguard Worker      evt6.type = TCP_EVENT_TYPE_CLOSE;
431*387f9dfdSAndroid Build Coastguard Worker      evt6.pid = pid >> 32;
432*387f9dfdSAndroid Build Coastguard Worker      evt6.ip = ipver;
433*387f9dfdSAndroid Build Coastguard Worker      evt6.saddr = t.saddr;
434*387f9dfdSAndroid Build Coastguard Worker      evt6.daddr = t.daddr;
435*387f9dfdSAndroid Build Coastguard Worker      evt6.sport = ntohs(t.sport);
436*387f9dfdSAndroid Build Coastguard Worker      evt6.dport = ntohs(t.dport);
437*387f9dfdSAndroid Build Coastguard Worker      evt6.netns = t.netns;
438*387f9dfdSAndroid Build Coastguard Worker      bpf_get_current_comm(&evt6.comm, sizeof(evt6.comm));
439*387f9dfdSAndroid Build Coastguard Worker
440*387f9dfdSAndroid Build Coastguard Worker      tcp_ipv6_event.perf_submit(ctx, &evt6, sizeof(evt6));
441*387f9dfdSAndroid Build Coastguard Worker  }
442*387f9dfdSAndroid Build Coastguard Worker  // else drop
443*387f9dfdSAndroid Build Coastguard Worker
444*387f9dfdSAndroid Build Coastguard Worker  return 0;
445*387f9dfdSAndroid Build Coastguard Worker};
446*387f9dfdSAndroid Build Coastguard Worker
447*387f9dfdSAndroid Build Coastguard Workerint trace_accept_return(struct pt_regs *ctx)
448*387f9dfdSAndroid Build Coastguard Worker{
449*387f9dfdSAndroid Build Coastguard Worker  if (container_should_be_filtered()) {
450*387f9dfdSAndroid Build Coastguard Worker    return 0;
451*387f9dfdSAndroid Build Coastguard Worker  }
452*387f9dfdSAndroid Build Coastguard Worker
453*387f9dfdSAndroid Build Coastguard Worker  struct sock *newsk = (struct sock *)PT_REGS_RC(ctx);
454*387f9dfdSAndroid Build Coastguard Worker  u64 pid = bpf_get_current_pid_tgid();
455*387f9dfdSAndroid Build Coastguard Worker
456*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_PID##
457*387f9dfdSAndroid Build Coastguard Worker
458*387f9dfdSAndroid Build Coastguard Worker  if (newsk == NULL) {
459*387f9dfdSAndroid Build Coastguard Worker      return 0;
460*387f9dfdSAndroid Build Coastguard Worker  }
461*387f9dfdSAndroid Build Coastguard Worker
462*387f9dfdSAndroid Build Coastguard Worker  // pull in details
463*387f9dfdSAndroid Build Coastguard Worker  u16 lport = 0, dport = 0;
464*387f9dfdSAndroid Build Coastguard Worker  u32 net_ns_inum = 0;
465*387f9dfdSAndroid Build Coastguard Worker  u8 ipver = 0;
466*387f9dfdSAndroid Build Coastguard Worker
467*387f9dfdSAndroid Build Coastguard Worker  dport = newsk->__sk_common.skc_dport;
468*387f9dfdSAndroid Build Coastguard Worker  lport = newsk->__sk_common.skc_num;
469*387f9dfdSAndroid Build Coastguard Worker
470*387f9dfdSAndroid Build Coastguard Worker  // Get network namespace id, if kernel supports it
471*387f9dfdSAndroid Build Coastguard Worker#ifdef CONFIG_NET_NS
472*387f9dfdSAndroid Build Coastguard Worker  net_ns_inum = newsk->__sk_common.skc_net.net->ns.inum;
473*387f9dfdSAndroid Build Coastguard Worker#endif
474*387f9dfdSAndroid Build Coastguard Worker
475*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_NETNS##
476*387f9dfdSAndroid Build Coastguard Worker
477*387f9dfdSAndroid Build Coastguard Worker  u16 family = newsk->__sk_common.skc_family;
478*387f9dfdSAndroid Build Coastguard Worker  ##FILTER_FAMILY##
479*387f9dfdSAndroid Build Coastguard Worker
480*387f9dfdSAndroid Build Coastguard Worker  if (check_family(newsk, AF_INET)) {
481*387f9dfdSAndroid Build Coastguard Worker      ipver = 4;
482*387f9dfdSAndroid Build Coastguard Worker
483*387f9dfdSAndroid Build Coastguard Worker      struct tcp_ipv4_event_t evt4 = { 0 };
484*387f9dfdSAndroid Build Coastguard Worker
485*387f9dfdSAndroid Build Coastguard Worker      evt4.ts_ns = bpf_ktime_get_ns();
486*387f9dfdSAndroid Build Coastguard Worker      evt4.type = TCP_EVENT_TYPE_ACCEPT;
487*387f9dfdSAndroid Build Coastguard Worker      evt4.netns = net_ns_inum;
488*387f9dfdSAndroid Build Coastguard Worker      evt4.pid = pid >> 32;
489*387f9dfdSAndroid Build Coastguard Worker      evt4.ip = ipver;
490*387f9dfdSAndroid Build Coastguard Worker
491*387f9dfdSAndroid Build Coastguard Worker      evt4.saddr = newsk->__sk_common.skc_rcv_saddr;
492*387f9dfdSAndroid Build Coastguard Worker      evt4.daddr = newsk->__sk_common.skc_daddr;
493*387f9dfdSAndroid Build Coastguard Worker
494*387f9dfdSAndroid Build Coastguard Worker      evt4.sport = lport;
495*387f9dfdSAndroid Build Coastguard Worker      evt4.dport = ntohs(dport);
496*387f9dfdSAndroid Build Coastguard Worker      bpf_get_current_comm(&evt4.comm, sizeof(evt4.comm));
497*387f9dfdSAndroid Build Coastguard Worker
498*387f9dfdSAndroid Build Coastguard Worker      // do not send event if IP address is 0.0.0.0 or port is 0
499*387f9dfdSAndroid Build Coastguard Worker      if (evt4.saddr != 0 && evt4.daddr != 0 &&
500*387f9dfdSAndroid Build Coastguard Worker          evt4.sport != 0 && evt4.dport != 0) {
501*387f9dfdSAndroid Build Coastguard Worker          tcp_ipv4_event.perf_submit(ctx, &evt4, sizeof(evt4));
502*387f9dfdSAndroid Build Coastguard Worker      }
503*387f9dfdSAndroid Build Coastguard Worker  } else if (check_family(newsk, AF_INET6)) {
504*387f9dfdSAndroid Build Coastguard Worker      ipver = 6;
505*387f9dfdSAndroid Build Coastguard Worker
506*387f9dfdSAndroid Build Coastguard Worker      struct tcp_ipv6_event_t evt6 = { 0 };
507*387f9dfdSAndroid Build Coastguard Worker
508*387f9dfdSAndroid Build Coastguard Worker      evt6.ts_ns = bpf_ktime_get_ns();
509*387f9dfdSAndroid Build Coastguard Worker      evt6.type = TCP_EVENT_TYPE_ACCEPT;
510*387f9dfdSAndroid Build Coastguard Worker      evt6.netns = net_ns_inum;
511*387f9dfdSAndroid Build Coastguard Worker      evt6.pid = pid >> 32;
512*387f9dfdSAndroid Build Coastguard Worker      evt6.ip = ipver;
513*387f9dfdSAndroid Build Coastguard Worker
514*387f9dfdSAndroid Build Coastguard Worker      bpf_probe_read_kernel(&evt6.saddr, sizeof(evt6.saddr),
515*387f9dfdSAndroid Build Coastguard Worker                     newsk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
516*387f9dfdSAndroid Build Coastguard Worker      bpf_probe_read_kernel(&evt6.daddr, sizeof(evt6.daddr),
517*387f9dfdSAndroid Build Coastguard Worker                     newsk->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
518*387f9dfdSAndroid Build Coastguard Worker
519*387f9dfdSAndroid Build Coastguard Worker      evt6.sport = lport;
520*387f9dfdSAndroid Build Coastguard Worker      evt6.dport = ntohs(dport);
521*387f9dfdSAndroid Build Coastguard Worker      bpf_get_current_comm(&evt6.comm, sizeof(evt6.comm));
522*387f9dfdSAndroid Build Coastguard Worker
523*387f9dfdSAndroid Build Coastguard Worker      // do not send event if IP address is 0.0.0.0 or port is 0
524*387f9dfdSAndroid Build Coastguard Worker      if (evt6.saddr != 0 && evt6.daddr != 0 &&
525*387f9dfdSAndroid Build Coastguard Worker          evt6.sport != 0 && evt6.dport != 0) {
526*387f9dfdSAndroid Build Coastguard Worker          tcp_ipv6_event.perf_submit(ctx, &evt6, sizeof(evt6));
527*387f9dfdSAndroid Build Coastguard Worker      }
528*387f9dfdSAndroid Build Coastguard Worker  }
529*387f9dfdSAndroid Build Coastguard Worker  // else drop
530*387f9dfdSAndroid Build Coastguard Worker
531*387f9dfdSAndroid Build Coastguard Worker  return 0;
532*387f9dfdSAndroid Build Coastguard Worker}
533*387f9dfdSAndroid Build Coastguard Worker"""
534*387f9dfdSAndroid Build Coastguard Worker
535*387f9dfdSAndroid Build Coastguard Workerverbose_types = {"C": "connect", "A": "accept",
536*387f9dfdSAndroid Build Coastguard Worker                 "X": "close", "U": "unknown"}
537*387f9dfdSAndroid Build Coastguard Worker
538*387f9dfdSAndroid Build Coastguard Worker
539*387f9dfdSAndroid Build Coastguard Workerdef print_ipv4_event(cpu, data, size):
540*387f9dfdSAndroid Build Coastguard Worker    event = b["tcp_ipv4_event"].event(data)
541*387f9dfdSAndroid Build Coastguard Worker    global start_ts
542*387f9dfdSAndroid Build Coastguard Worker
543*387f9dfdSAndroid Build Coastguard Worker    if args.timestamp:
544*387f9dfdSAndroid Build Coastguard Worker        if start_ts == 0:
545*387f9dfdSAndroid Build Coastguard Worker            start_ts = event.ts_ns
546*387f9dfdSAndroid Build Coastguard Worker        if args.verbose:
547*387f9dfdSAndroid Build Coastguard Worker            print("%-14d" % (event.ts_ns - start_ts), end="")
548*387f9dfdSAndroid Build Coastguard Worker        else:
549*387f9dfdSAndroid Build Coastguard Worker            print("%-9.3f" % ((event.ts_ns - start_ts) / 1000000000.0), end="")
550*387f9dfdSAndroid Build Coastguard Worker    if event.type == 1:
551*387f9dfdSAndroid Build Coastguard Worker        type_str = "C"
552*387f9dfdSAndroid Build Coastguard Worker    elif event.type == 2:
553*387f9dfdSAndroid Build Coastguard Worker        type_str = "A"
554*387f9dfdSAndroid Build Coastguard Worker    elif event.type == 3:
555*387f9dfdSAndroid Build Coastguard Worker        type_str = "X"
556*387f9dfdSAndroid Build Coastguard Worker    else:
557*387f9dfdSAndroid Build Coastguard Worker        type_str = "U"
558*387f9dfdSAndroid Build Coastguard Worker
559*387f9dfdSAndroid Build Coastguard Worker    if args.verbose:
560*387f9dfdSAndroid Build Coastguard Worker        print("%-12s " % (verbose_types[type_str]), end="")
561*387f9dfdSAndroid Build Coastguard Worker    else:
562*387f9dfdSAndroid Build Coastguard Worker        print("%-2s " % (type_str), end="")
563*387f9dfdSAndroid Build Coastguard Worker
564*387f9dfdSAndroid Build Coastguard Worker    print("%-6d %-16s %-2d %-16s %-16s %-6d %-6d" %
565*387f9dfdSAndroid Build Coastguard Worker          (event.pid, event.comm.decode('utf-8', 'replace'),
566*387f9dfdSAndroid Build Coastguard Worker           event.ip,
567*387f9dfdSAndroid Build Coastguard Worker           inet_ntop(AF_INET, pack("I", event.saddr)),
568*387f9dfdSAndroid Build Coastguard Worker           inet_ntop(AF_INET, pack("I", event.daddr)),
569*387f9dfdSAndroid Build Coastguard Worker           event.sport,
570*387f9dfdSAndroid Build Coastguard Worker           event.dport), end="")
571*387f9dfdSAndroid Build Coastguard Worker    if args.verbose and not args.netns:
572*387f9dfdSAndroid Build Coastguard Worker        print(" %-8d" % event.netns)
573*387f9dfdSAndroid Build Coastguard Worker    else:
574*387f9dfdSAndroid Build Coastguard Worker        print()
575*387f9dfdSAndroid Build Coastguard Worker
576*387f9dfdSAndroid Build Coastguard Worker
577*387f9dfdSAndroid Build Coastguard Workerdef print_ipv6_event(cpu, data, size):
578*387f9dfdSAndroid Build Coastguard Worker    event = b["tcp_ipv6_event"].event(data)
579*387f9dfdSAndroid Build Coastguard Worker    global start_ts
580*387f9dfdSAndroid Build Coastguard Worker    if args.timestamp:
581*387f9dfdSAndroid Build Coastguard Worker        if start_ts == 0:
582*387f9dfdSAndroid Build Coastguard Worker            start_ts = event.ts_ns
583*387f9dfdSAndroid Build Coastguard Worker        if args.verbose:
584*387f9dfdSAndroid Build Coastguard Worker            print("%-14d" % (event.ts_ns - start_ts), end="")
585*387f9dfdSAndroid Build Coastguard Worker        else:
586*387f9dfdSAndroid Build Coastguard Worker            print("%-9.3f" % ((event.ts_ns - start_ts) / 1000000000.0), end="")
587*387f9dfdSAndroid Build Coastguard Worker    if event.type == 1:
588*387f9dfdSAndroid Build Coastguard Worker        type_str = "C"
589*387f9dfdSAndroid Build Coastguard Worker    elif event.type == 2:
590*387f9dfdSAndroid Build Coastguard Worker        type_str = "A"
591*387f9dfdSAndroid Build Coastguard Worker    elif event.type == 3:
592*387f9dfdSAndroid Build Coastguard Worker        type_str = "X"
593*387f9dfdSAndroid Build Coastguard Worker    else:
594*387f9dfdSAndroid Build Coastguard Worker        type_str = "U"
595*387f9dfdSAndroid Build Coastguard Worker
596*387f9dfdSAndroid Build Coastguard Worker    if args.verbose:
597*387f9dfdSAndroid Build Coastguard Worker        print("%-12s " % (verbose_types[type_str]), end="")
598*387f9dfdSAndroid Build Coastguard Worker    else:
599*387f9dfdSAndroid Build Coastguard Worker        print("%-2s " % (type_str), end="")
600*387f9dfdSAndroid Build Coastguard Worker
601*387f9dfdSAndroid Build Coastguard Worker    print("%-6d %-16s %-2d %-16s %-16s %-6d %-6d" %
602*387f9dfdSAndroid Build Coastguard Worker          (event.pid, event.comm.decode('utf-8', 'replace'),
603*387f9dfdSAndroid Build Coastguard Worker           event.ip,
604*387f9dfdSAndroid Build Coastguard Worker           "[" + inet_ntop(AF_INET6, event.saddr) + "]",
605*387f9dfdSAndroid Build Coastguard Worker           "[" + inet_ntop(AF_INET6, event.daddr) + "]",
606*387f9dfdSAndroid Build Coastguard Worker           event.sport,
607*387f9dfdSAndroid Build Coastguard Worker           event.dport), end="")
608*387f9dfdSAndroid Build Coastguard Worker    if args.verbose and not args.netns:
609*387f9dfdSAndroid Build Coastguard Worker        print(" %-8d" % event.netns)
610*387f9dfdSAndroid Build Coastguard Worker    else:
611*387f9dfdSAndroid Build Coastguard Worker        print()
612*387f9dfdSAndroid Build Coastguard Worker
613*387f9dfdSAndroid Build Coastguard Worker
614*387f9dfdSAndroid Build Coastguard Workerpid_filter = ""
615*387f9dfdSAndroid Build Coastguard Workernetns_filter = ""
616*387f9dfdSAndroid Build Coastguard Worker
617*387f9dfdSAndroid Build Coastguard Workerif args.pid:
618*387f9dfdSAndroid Build Coastguard Worker    pid_filter = 'if (pid >> 32 != %d) { return 0; }' % args.pid
619*387f9dfdSAndroid Build Coastguard Workerif args.netns:
620*387f9dfdSAndroid Build Coastguard Worker    netns_filter = 'if (net_ns_inum != %d) { return 0; }' % args.netns
621*387f9dfdSAndroid Build Coastguard Workerif args.ipv4:
622*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('##FILTER_FAMILY##',
623*387f9dfdSAndroid Build Coastguard Worker        'if (family != AF_INET) { return 0; }')
624*387f9dfdSAndroid Build Coastguard Workerelif args.ipv6:
625*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('##FILTER_FAMILY##',
626*387f9dfdSAndroid Build Coastguard Worker        'if (family != AF_INET6) { return 0; }')
627*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('##FILTER_FAMILY##', '')
628*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('##FILTER_PID##', pid_filter)
629*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('##FILTER_NETNS##', netns_filter)
630*387f9dfdSAndroid Build Coastguard Workerbpf_text = filter_by_containers(args) + bpf_text
631*387f9dfdSAndroid Build Coastguard Worker
632*387f9dfdSAndroid Build Coastguard Workerif args.ebpf:
633*387f9dfdSAndroid Build Coastguard Worker    print(bpf_text)
634*387f9dfdSAndroid Build Coastguard Worker    exit()
635*387f9dfdSAndroid Build Coastguard Worker
636*387f9dfdSAndroid Build Coastguard Worker# initialize BPF
637*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
638*387f9dfdSAndroid Build Coastguard Workerif args.ipv4:
639*387f9dfdSAndroid Build Coastguard Worker    b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_entry")
640*387f9dfdSAndroid Build Coastguard Worker    b.attach_kretprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_return")
641*387f9dfdSAndroid Build Coastguard Workerelif args.ipv6:
642*387f9dfdSAndroid Build Coastguard Worker    b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_entry")
643*387f9dfdSAndroid Build Coastguard Worker    b.attach_kretprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_return")
644*387f9dfdSAndroid Build Coastguard Workerelse:
645*387f9dfdSAndroid Build Coastguard Worker    b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_entry")
646*387f9dfdSAndroid Build Coastguard Worker    b.attach_kretprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_return")
647*387f9dfdSAndroid Build Coastguard Worker    b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_entry")
648*387f9dfdSAndroid Build Coastguard Worker    b.attach_kretprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_return")
649*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="tcp_set_state", fn_name="trace_tcp_set_state_entry")
650*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="tcp_close", fn_name="trace_close_entry")
651*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="inet_csk_accept", fn_name="trace_accept_return")
652*387f9dfdSAndroid Build Coastguard Worker
653*387f9dfdSAndroid Build Coastguard Workerprint("Tracing TCP established connections. Ctrl-C to end.")
654*387f9dfdSAndroid Build Coastguard Worker
655*387f9dfdSAndroid Build Coastguard Worker# header
656*387f9dfdSAndroid Build Coastguard Workerif args.verbose:
657*387f9dfdSAndroid Build Coastguard Worker    if args.timestamp:
658*387f9dfdSAndroid Build Coastguard Worker        print("%-14s" % ("TIME(ns)"), end="")
659*387f9dfdSAndroid Build Coastguard Worker    print("%-12s %-6s %-16s %-2s %-16s %-16s %-6s %-7s" % ("TYPE",
660*387f9dfdSAndroid Build Coastguard Worker          "PID", "COMM", "IP", "SADDR", "DADDR", "SPORT", "DPORT"), end="")
661*387f9dfdSAndroid Build Coastguard Worker    if not args.netns:
662*387f9dfdSAndroid Build Coastguard Worker        print("%-8s" % "NETNS", end="")
663*387f9dfdSAndroid Build Coastguard Worker    print()
664*387f9dfdSAndroid Build Coastguard Workerelse:
665*387f9dfdSAndroid Build Coastguard Worker    if args.timestamp:
666*387f9dfdSAndroid Build Coastguard Worker        print("%-9s" % ("TIME(s)"), end="")
667*387f9dfdSAndroid Build Coastguard Worker    print("%-2s %-6s %-16s %-2s %-16s %-16s %-6s %-6s" %
668*387f9dfdSAndroid Build Coastguard Worker          ("T", "PID", "COMM", "IP", "SADDR", "DADDR", "SPORT", "DPORT"))
669*387f9dfdSAndroid Build Coastguard Worker
670*387f9dfdSAndroid Build Coastguard Workerstart_ts = 0
671*387f9dfdSAndroid Build Coastguard Worker
672*387f9dfdSAndroid Build Coastguard Worker
673*387f9dfdSAndroid Build Coastguard Workerb["tcp_ipv4_event"].open_perf_buffer(print_ipv4_event)
674*387f9dfdSAndroid Build Coastguard Workerb["tcp_ipv6_event"].open_perf_buffer(print_ipv6_event)
675*387f9dfdSAndroid Build Coastguard Workerwhile True:
676*387f9dfdSAndroid Build Coastguard Worker    try:
677*387f9dfdSAndroid Build Coastguard Worker        b.perf_buffer_poll()
678*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
679*387f9dfdSAndroid Build Coastguard Worker        exit()
680