xref: /aosp_15_r20/external/bcc/examples/tracing/tcpv4connect.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python
2*387f9dfdSAndroid Build Coastguard Worker#
3*387f9dfdSAndroid Build Coastguard Worker# tcpv4connect	Trace TCP IPv4 connect()s.
4*387f9dfdSAndroid Build Coastguard Worker#		For Linux, uses BCC, eBPF. Embedded C.
5*387f9dfdSAndroid Build Coastguard Worker#
6*387f9dfdSAndroid Build Coastguard Worker# USAGE: tcpv4connect [-h] [-t] [-p PID]
7*387f9dfdSAndroid Build Coastguard Worker#
8*387f9dfdSAndroid Build Coastguard Worker# This is provided as a basic example of TCP connection & socket tracing.
9*387f9dfdSAndroid Build Coastguard Worker#
10*387f9dfdSAndroid Build Coastguard Worker# All IPv4 connection attempts are traced, even if they ultimately fail.
11*387f9dfdSAndroid Build Coastguard Worker#
12*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) 2015 Brendan Gregg.
13*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
14*387f9dfdSAndroid Build Coastguard Worker#
15*387f9dfdSAndroid Build Coastguard Worker# 15-Oct-2015	Brendan Gregg	Created this.
16*387f9dfdSAndroid Build Coastguard Worker
17*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
18*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
19*387f9dfdSAndroid Build Coastguard Workerfrom bcc.utils import printb
20*387f9dfdSAndroid Build Coastguard Worker
21*387f9dfdSAndroid Build Coastguard Worker# define BPF program
22*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
23*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
24*387f9dfdSAndroid Build Coastguard Worker#include <net/sock.h>
25*387f9dfdSAndroid Build Coastguard Worker#include <bcc/proto.h>
26*387f9dfdSAndroid Build Coastguard Worker
27*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(currsock, u32, struct sock *);
28*387f9dfdSAndroid Build Coastguard Worker
29*387f9dfdSAndroid Build Coastguard Workerint kprobe__tcp_v4_connect(struct pt_regs *ctx, struct sock *sk)
30*387f9dfdSAndroid Build Coastguard Worker{
31*387f9dfdSAndroid Build Coastguard Worker	u32 pid = bpf_get_current_pid_tgid();
32*387f9dfdSAndroid Build Coastguard Worker
33*387f9dfdSAndroid Build Coastguard Worker	// stash the sock ptr for lookup on return
34*387f9dfdSAndroid Build Coastguard Worker	currsock.update(&pid, &sk);
35*387f9dfdSAndroid Build Coastguard Worker
36*387f9dfdSAndroid Build Coastguard Worker	return 0;
37*387f9dfdSAndroid Build Coastguard Worker};
38*387f9dfdSAndroid Build Coastguard Worker
39*387f9dfdSAndroid Build Coastguard Workerint kretprobe__tcp_v4_connect(struct pt_regs *ctx)
40*387f9dfdSAndroid Build Coastguard Worker{
41*387f9dfdSAndroid Build Coastguard Worker	int ret = PT_REGS_RC(ctx);
42*387f9dfdSAndroid Build Coastguard Worker	u32 pid = bpf_get_current_pid_tgid();
43*387f9dfdSAndroid Build Coastguard Worker
44*387f9dfdSAndroid Build Coastguard Worker	struct sock **skpp;
45*387f9dfdSAndroid Build Coastguard Worker	skpp = currsock.lookup(&pid);
46*387f9dfdSAndroid Build Coastguard Worker	if (skpp == 0) {
47*387f9dfdSAndroid Build Coastguard Worker		return 0;	// missed entry
48*387f9dfdSAndroid Build Coastguard Worker	}
49*387f9dfdSAndroid Build Coastguard Worker
50*387f9dfdSAndroid Build Coastguard Worker	if (ret != 0) {
51*387f9dfdSAndroid Build Coastguard Worker		// failed to send SYNC packet, may not have populated
52*387f9dfdSAndroid Build Coastguard Worker		// socket __sk_common.{skc_rcv_saddr, ...}
53*387f9dfdSAndroid Build Coastguard Worker		currsock.delete(&pid);
54*387f9dfdSAndroid Build Coastguard Worker		return 0;
55*387f9dfdSAndroid Build Coastguard Worker	}
56*387f9dfdSAndroid Build Coastguard Worker
57*387f9dfdSAndroid Build Coastguard Worker	// pull in details
58*387f9dfdSAndroid Build Coastguard Worker	struct sock *skp = *skpp;
59*387f9dfdSAndroid Build Coastguard Worker	u32 saddr = skp->__sk_common.skc_rcv_saddr;
60*387f9dfdSAndroid Build Coastguard Worker	u32 daddr = skp->__sk_common.skc_daddr;
61*387f9dfdSAndroid Build Coastguard Worker	u16 dport = skp->__sk_common.skc_dport;
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker	// output
64*387f9dfdSAndroid Build Coastguard Worker	bpf_trace_printk("trace_tcp4connect %x %x %d\\n", saddr, daddr, ntohs(dport));
65*387f9dfdSAndroid Build Coastguard Worker
66*387f9dfdSAndroid Build Coastguard Worker	currsock.delete(&pid);
67*387f9dfdSAndroid Build Coastguard Worker
68*387f9dfdSAndroid Build Coastguard Worker	return 0;
69*387f9dfdSAndroid Build Coastguard Worker}
70*387f9dfdSAndroid Build Coastguard Worker"""
71*387f9dfdSAndroid Build Coastguard Worker
72*387f9dfdSAndroid Build Coastguard Worker# initialize BPF
73*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
74*387f9dfdSAndroid Build Coastguard Worker
75*387f9dfdSAndroid Build Coastguard Worker# header
76*387f9dfdSAndroid Build Coastguard Workerprint("%-6s %-12s %-16s %-16s %-4s" % ("PID", "COMM", "SADDR", "DADDR",
77*387f9dfdSAndroid Build Coastguard Worker    "DPORT"))
78*387f9dfdSAndroid Build Coastguard Worker
79*387f9dfdSAndroid Build Coastguard Workerdef inet_ntoa(addr):
80*387f9dfdSAndroid Build Coastguard Worker	dq = b''
81*387f9dfdSAndroid Build Coastguard Worker	for i in range(0, 4):
82*387f9dfdSAndroid Build Coastguard Worker		dq = dq + str(addr & 0xff).encode()
83*387f9dfdSAndroid Build Coastguard Worker		if (i != 3):
84*387f9dfdSAndroid Build Coastguard Worker			dq = dq + b'.'
85*387f9dfdSAndroid Build Coastguard Worker		addr = addr >> 8
86*387f9dfdSAndroid Build Coastguard Worker	return dq
87*387f9dfdSAndroid Build Coastguard Worker
88*387f9dfdSAndroid Build Coastguard Worker# filter and format output
89*387f9dfdSAndroid Build Coastguard Workerwhile 1:
90*387f9dfdSAndroid Build Coastguard Worker	# Read messages from kernel pipe
91*387f9dfdSAndroid Build Coastguard Worker	try:
92*387f9dfdSAndroid Build Coastguard Worker	    (task, pid, cpu, flags, ts, msg) = b.trace_fields()
93*387f9dfdSAndroid Build Coastguard Worker	    (_tag, saddr_hs, daddr_hs, dport_s) = msg.split(b" ")
94*387f9dfdSAndroid Build Coastguard Worker	except ValueError:
95*387f9dfdSAndroid Build Coastguard Worker	    # Ignore messages from other tracers
96*387f9dfdSAndroid Build Coastguard Worker	    continue
97*387f9dfdSAndroid Build Coastguard Worker	except KeyboardInterrupt:
98*387f9dfdSAndroid Build Coastguard Worker	    exit()
99*387f9dfdSAndroid Build Coastguard Worker
100*387f9dfdSAndroid Build Coastguard Worker	# Ignore messages from other tracers
101*387f9dfdSAndroid Build Coastguard Worker	if _tag.decode() != "trace_tcp4connect":
102*387f9dfdSAndroid Build Coastguard Worker	    continue
103*387f9dfdSAndroid Build Coastguard Worker
104*387f9dfdSAndroid Build Coastguard Worker	printb(b"%-6d %-12.12s %-16s %-16s %-4s" % (pid, task,
105*387f9dfdSAndroid Build Coastguard Worker	    inet_ntoa(int(saddr_hs, 16)),
106*387f9dfdSAndroid Build Coastguard Worker	    inet_ntoa(int(daddr_hs, 16)),
107*387f9dfdSAndroid Build Coastguard Worker	    dport_s))
108