blob: 40963cfdd61046599e90ea9357c71de7c5f1ad1a [file] [log] [blame]
Alexey Ivanovcc01a9c2019-01-16 09:50:46 -08001#!/usr/bin/python
Brendan Gregg870b1cd2015-09-25 17:01:17 -07002#
3# tcpv4connect Trace TCP IPv4 connect()s.
4# For Linux, uses BCC, eBPF. Embedded C.
5#
6# USAGE: tcpv4connect [-h] [-t] [-p PID]
7#
Brendan Greggf06d3b42015-10-15 17:21:32 -07008# This is provided as a basic example of TCP connection & socket tracing.
9#
10# All IPv4 connection attempts are traced, even if they ultimately fail.
11#
Brendan Gregg870b1cd2015-09-25 17:01:17 -070012# Copyright (c) 2015 Brendan Gregg.
13# Licensed under the Apache License, Version 2.0 (the "License")
14#
Brendan Greggf06d3b42015-10-15 17:21:32 -070015# 15-Oct-2015 Brendan Gregg Created this.
Brendan Gregg870b1cd2015-09-25 17:01:17 -070016
17from __future__ import print_function
18from bcc import BPF
Gary Linbb65bea2019-02-27 16:52:35 +080019from bcc.utils import printb
Brendan Gregg870b1cd2015-09-25 17:01:17 -070020
21# define BPF program
22bpf_text = """
23#include <uapi/linux/ptrace.h>
24#include <net/sock.h>
25#include <bcc/proto.h>
26
27BPF_HASH(currsock, u32, struct sock *);
28
29int kprobe__tcp_v4_connect(struct pt_regs *ctx, struct sock *sk)
30{
31 u32 pid = bpf_get_current_pid_tgid();
Brendan Gregg870b1cd2015-09-25 17:01:17 -070032
33 // stash the sock ptr for lookup on return
34 currsock.update(&pid, &sk);
35
36 return 0;
37};
38
39int kretprobe__tcp_v4_connect(struct pt_regs *ctx)
40{
Naveen N. Rao4afa96a2016-05-03 14:54:21 +053041 int ret = PT_REGS_RC(ctx);
Brendan Gregg870b1cd2015-09-25 17:01:17 -070042 u32 pid = bpf_get_current_pid_tgid();
43
44 struct sock **skpp;
45 skpp = currsock.lookup(&pid);
46 if (skpp == 0) {
47 return 0; // missed entry
48 }
49
Yonghong Song366eb2e2015-10-07 08:59:42 -070050 if (ret != 0) {
Brendan Greggf06d3b42015-10-15 17:21:32 -070051 // failed to send SYNC packet, may not have populated
52 // socket __sk_common.{skc_rcv_saddr, ...}
Yonghong Song366eb2e2015-10-07 08:59:42 -070053 currsock.delete(&pid);
54 return 0;
55 }
56
Brendan Gregg870b1cd2015-09-25 17:01:17 -070057 // pull in details
58 struct sock *skp = *skpp;
Paul Chaignoneae0acf2017-08-05 23:04:41 +020059 u32 saddr = skp->__sk_common.skc_rcv_saddr;
60 u32 daddr = skp->__sk_common.skc_daddr;
61 u16 dport = skp->__sk_common.skc_dport;
Brendan Gregg870b1cd2015-09-25 17:01:17 -070062
63 // output
Jean-Tiare Le Bigotd0764aa2016-02-21 23:45:29 +010064 bpf_trace_printk("trace_tcp4connect %x %x %d\\n", saddr, daddr, ntohs(dport));
Brendan Gregg870b1cd2015-09-25 17:01:17 -070065
66 currsock.delete(&pid);
67
68 return 0;
69}
70"""
71
Brendan Gregg870b1cd2015-09-25 17:01:17 -070072# initialize BPF
73b = BPF(text=bpf_text)
74
75# header
Brendan Gregg870b1cd2015-09-25 17:01:17 -070076print("%-6s %-12s %-16s %-16s %-4s" % ("PID", "COMM", "SADDR", "DADDR",
77 "DPORT"))
78
Brendan Gregg870b1cd2015-09-25 17:01:17 -070079def inet_ntoa(addr):
Gary Linbb65bea2019-02-27 16:52:35 +080080 dq = b''
Brendan Gregg870b1cd2015-09-25 17:01:17 -070081 for i in range(0, 4):
Gary Linbb65bea2019-02-27 16:52:35 +080082 dq = dq + str(addr & 0xff).encode()
Brendan Gregg870b1cd2015-09-25 17:01:17 -070083 if (i != 3):
Gary Linbb65bea2019-02-27 16:52:35 +080084 dq = dq + b'.'
Brendan Gregg870b1cd2015-09-25 17:01:17 -070085 addr = addr >> 8
86 return dq
87
Jean-Tiare Le Bigotd0764aa2016-02-21 23:45:29 +010088# filter and format output
Brendan Gregg870b1cd2015-09-25 17:01:17 -070089while 1:
Iago López Galeiras5bd242c2016-09-08 16:45:11 +020090 # Read messages from kernel pipe
91 try:
92 (task, pid, cpu, flags, ts, msg) = b.trace_fields()
Gary Linbb65bea2019-02-27 16:52:35 +080093 (_tag, saddr_hs, daddr_hs, dport_s) = msg.split(b" ")
Iago López Galeiras5bd242c2016-09-08 16:45:11 +020094 except ValueError:
95 # Ignore messages from other tracers
96 continue
Gary Lin593339d2019-02-27 16:54:44 +080097 except KeyboardInterrupt:
98 exit()
Jean-Tiare Le Bigotd0764aa2016-02-21 23:45:29 +010099
Iago López Galeiras5bd242c2016-09-08 16:45:11 +0200100 # Ignore messages from other tracers
Zdravko Bozakovd3ceae02021-09-28 22:45:17 +0200101 if _tag.decode() != "trace_tcp4connect":
Iago López Galeiras5bd242c2016-09-08 16:45:11 +0200102 continue
Brendan Gregg870b1cd2015-09-25 17:01:17 -0700103
Gary Linbb65bea2019-02-27 16:52:35 +0800104 printb(b"%-6d %-12.12s %-16s %-16s %-4s" % (pid, task,
Brendan Gregg870b1cd2015-09-25 17:01:17 -0700105 inet_ntoa(int(saddr_hs, 16)),
106 inet_ntoa(int(daddr_hs, 16)),
107 dport_s))