xref: /aosp_15_r20/external/bcc/examples/tracing/undump.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python
2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports
3*387f9dfdSAndroid Build Coastguard Worker#
4*387f9dfdSAndroid Build Coastguard Worker# undump        Dump UNIX socket packets.
5*387f9dfdSAndroid Build Coastguard Worker#               For Linux, uses BCC, eBPF. Embedded C.
6*387f9dfdSAndroid Build Coastguard Worker# USAGE: undump [-h] [-t] [-p PID]
7*387f9dfdSAndroid Build Coastguard Worker#
8*387f9dfdSAndroid Build Coastguard Worker# This uses dynamic tracing of kernel functions, and will need to be updated
9*387f9dfdSAndroid Build Coastguard Worker# to match kernel changes.
10*387f9dfdSAndroid Build Coastguard Worker#
11*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) 2021 Rong Tao.
12*387f9dfdSAndroid Build Coastguard Worker# Licensed under the GPL License, Version 2.0
13*387f9dfdSAndroid Build Coastguard Worker#
14*387f9dfdSAndroid Build Coastguard Worker# 27-Aug-2021   Rong Tao   Created this.
15*387f9dfdSAndroid Build Coastguard Worker# 17-Sep-2021   Rong Tao   Simplify according to chenhengqi's suggestion
16*387f9dfdSAndroid Build Coastguard Worker#                           https://github.com/iovisor/bcc/pull/3615
17*387f9dfdSAndroid Build Coastguard Worker#
18*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
19*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
20*387f9dfdSAndroid Build Coastguard Workerfrom bcc.containers import filter_by_containers
21*387f9dfdSAndroid Build Coastguard Workerfrom bcc.utils import printb
22*387f9dfdSAndroid Build Coastguard Workerimport argparse
23*387f9dfdSAndroid Build Coastguard Workerfrom socket import inet_ntop, ntohs, AF_INET, AF_INET6
24*387f9dfdSAndroid Build Coastguard Workerfrom struct import pack
25*387f9dfdSAndroid Build Coastguard Workerfrom time import sleep
26*387f9dfdSAndroid Build Coastguard Workerfrom datetime import datetime
27*387f9dfdSAndroid Build Coastguard Workerimport sys
28*387f9dfdSAndroid Build Coastguard Worker
29*387f9dfdSAndroid Build Coastguard Worker# arguments
30*387f9dfdSAndroid Build Coastguard Workerexamples = """examples:
31*387f9dfdSAndroid Build Coastguard Worker    ./undump           # trace/dump all UNIX packets
32*387f9dfdSAndroid Build Coastguard Worker    ./undump -p 181    # only trace/dump PID 181
33*387f9dfdSAndroid Build Coastguard Worker"""
34*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(
35*387f9dfdSAndroid Build Coastguard Worker    description="Dump UNIX socket packets",
36*387f9dfdSAndroid Build Coastguard Worker    formatter_class=argparse.RawDescriptionHelpFormatter,
37*387f9dfdSAndroid Build Coastguard Worker    epilog=examples)
38*387f9dfdSAndroid Build Coastguard Worker
39*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid",
40*387f9dfdSAndroid Build Coastguard Worker        help="trace this PID only")
41*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
42*387f9dfdSAndroid Build Coastguard Worker
43*387f9dfdSAndroid Build Coastguard Worker# define BPF program
44*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
45*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
46*387f9dfdSAndroid Build Coastguard Worker#include <net/sock.h>
47*387f9dfdSAndroid Build Coastguard Worker#include <bcc/proto.h>
48*387f9dfdSAndroid Build Coastguard Worker#include <linux/aio.h>
49*387f9dfdSAndroid Build Coastguard Worker#include <linux/socket.h>
50*387f9dfdSAndroid Build Coastguard Worker#include <linux/net.h>
51*387f9dfdSAndroid Build Coastguard Worker#include <linux/fs.h>
52*387f9dfdSAndroid Build Coastguard Worker#include <linux/mount.h>
53*387f9dfdSAndroid Build Coastguard Worker#include <linux/module.h>
54*387f9dfdSAndroid Build Coastguard Worker#include <net/sock.h>
55*387f9dfdSAndroid Build Coastguard Worker#include <net/af_unix.h>
56*387f9dfdSAndroid Build Coastguard Worker
57*387f9dfdSAndroid Build Coastguard Worker#define MAX_PKT 512
58*387f9dfdSAndroid Build Coastguard Workerstruct recv_data_t {
59*387f9dfdSAndroid Build Coastguard Worker    u32 recv_len;
60*387f9dfdSAndroid Build Coastguard Worker    u8  pkt[MAX_PKT];
61*387f9dfdSAndroid Build Coastguard Worker};
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker// single element per-cpu array to hold the current event off the stack
64*387f9dfdSAndroid Build Coastguard WorkerBPF_PERCPU_ARRAY(unix_data, struct recv_data_t, 1);
65*387f9dfdSAndroid Build Coastguard Worker
66*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(unix_recv_events);
67*387f9dfdSAndroid Build Coastguard Worker
68*387f9dfdSAndroid Build Coastguard Workerint trace_unix_stream_read_actor(struct pt_regs *ctx)
69*387f9dfdSAndroid Build Coastguard Worker{
70*387f9dfdSAndroid Build Coastguard Worker    u32 zero = 0;
71*387f9dfdSAndroid Build Coastguard Worker    int ret = PT_REGS_RC(ctx);
72*387f9dfdSAndroid Build Coastguard Worker    u64 pid_tgid = bpf_get_current_pid_tgid();
73*387f9dfdSAndroid Build Coastguard Worker    u32 pid = pid_tgid >> 32;
74*387f9dfdSAndroid Build Coastguard Worker    u32 tid = pid_tgid;
75*387f9dfdSAndroid Build Coastguard Worker
76*387f9dfdSAndroid Build Coastguard Worker    FILTER_PID
77*387f9dfdSAndroid Build Coastguard Worker
78*387f9dfdSAndroid Build Coastguard Worker    struct sk_buff *skb = (struct sk_buff *)PT_REGS_PARM1(ctx);
79*387f9dfdSAndroid Build Coastguard Worker
80*387f9dfdSAndroid Build Coastguard Worker    struct recv_data_t *data = unix_data.lookup(&zero);
81*387f9dfdSAndroid Build Coastguard Worker    if (!data)
82*387f9dfdSAndroid Build Coastguard Worker        return 0;
83*387f9dfdSAndroid Build Coastguard Worker
84*387f9dfdSAndroid Build Coastguard Worker    unsigned int data_len = skb->len;
85*387f9dfdSAndroid Build Coastguard Worker    if(data_len > MAX_PKT)
86*387f9dfdSAndroid Build Coastguard Worker        return 0;
87*387f9dfdSAndroid Build Coastguard Worker
88*387f9dfdSAndroid Build Coastguard Worker    void *iodata = (void *)skb->data;
89*387f9dfdSAndroid Build Coastguard Worker    data->recv_len = data_len;
90*387f9dfdSAndroid Build Coastguard Worker
91*387f9dfdSAndroid Build Coastguard Worker    bpf_probe_read(data->pkt, data_len, iodata);
92*387f9dfdSAndroid Build Coastguard Worker    unix_recv_events.perf_submit(ctx, data, data_len+sizeof(u32));
93*387f9dfdSAndroid Build Coastguard Worker
94*387f9dfdSAndroid Build Coastguard Worker    return 0;
95*387f9dfdSAndroid Build Coastguard Worker}
96*387f9dfdSAndroid Build Coastguard Worker"""
97*387f9dfdSAndroid Build Coastguard Worker
98*387f9dfdSAndroid Build Coastguard Workerif args.pid:
99*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER_PID',
100*387f9dfdSAndroid Build Coastguard Worker        'if (pid != %s) { return 0; }' % args.pid)
101*387f9dfdSAndroid Build Coastguard Worker
102*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('FILTER_PID', '')
103*387f9dfdSAndroid Build Coastguard Worker
104*387f9dfdSAndroid Build Coastguard Worker# process event
105*387f9dfdSAndroid Build Coastguard Workerdef print_recv_pkg(cpu, data, size):
106*387f9dfdSAndroid Build Coastguard Worker    event = b["unix_recv_events"].event(data)
107*387f9dfdSAndroid Build Coastguard Worker    if args.pid:
108*387f9dfdSAndroid Build Coastguard Worker        print("PID \033[1;31m%s\033[m " % args.pid, end="")
109*387f9dfdSAndroid Build Coastguard Worker    print("Recv \033[1;31m%d\033[m bytes" % event.recv_len)
110*387f9dfdSAndroid Build Coastguard Worker
111*387f9dfdSAndroid Build Coastguard Worker    print("    ", end="")
112*387f9dfdSAndroid Build Coastguard Worker    for i in range(0, event.recv_len):
113*387f9dfdSAndroid Build Coastguard Worker        print("%02x " % event.pkt[i], end="")
114*387f9dfdSAndroid Build Coastguard Worker        sys.stdout.flush()
115*387f9dfdSAndroid Build Coastguard Worker        if (i+1)%16 == 0:
116*387f9dfdSAndroid Build Coastguard Worker            print("")
117*387f9dfdSAndroid Build Coastguard Worker            print("    ", end="")
118*387f9dfdSAndroid Build Coastguard Worker    print("")
119*387f9dfdSAndroid Build Coastguard Worker
120*387f9dfdSAndroid Build Coastguard Worker# initialize BPF
121*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
122*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="unix_stream_read_actor", fn_name="trace_unix_stream_read_actor")
123*387f9dfdSAndroid Build Coastguard Worker
124*387f9dfdSAndroid Build Coastguard Workerif args.pid:
125*387f9dfdSAndroid Build Coastguard Worker    print("Tracing \033[1;31mPID=%s\033[m UNIX socket packets ... Hit Ctrl-C to end" % args.pid)
126*387f9dfdSAndroid Build Coastguard Workerelse:
127*387f9dfdSAndroid Build Coastguard Worker    print("Tracing UNIX socket packets ... Hit Ctrl-C to end")
128*387f9dfdSAndroid Build Coastguard Worker
129*387f9dfdSAndroid Build Coastguard Workerstart_ts = 0
130*387f9dfdSAndroid Build Coastguard Worker
131*387f9dfdSAndroid Build Coastguard Worker# read events
132*387f9dfdSAndroid Build Coastguard Workerb["unix_recv_events"].open_perf_buffer(print_recv_pkg)
133*387f9dfdSAndroid Build Coastguard Worker
134*387f9dfdSAndroid Build Coastguard Workerwhile True:
135*387f9dfdSAndroid Build Coastguard Worker    try:
136*387f9dfdSAndroid Build Coastguard Worker        b.perf_buffer_poll()
137*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
138*387f9dfdSAndroid Build Coastguard Worker        exit()
139