blob: b5a10626b3c8a5d83d6cc833e2f097ef70f674a1 [file] [log] [blame]
Brendan Gregg870b1cd2015-09-25 17:01:17 -07001#!/usr/bin/python
2#
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
Brendan Gregg870b1cd2015-09-25 17:01:17 -070019
20# define BPF program
21bpf_text = """
22#include <uapi/linux/ptrace.h>
23#include <net/sock.h>
24#include <bcc/proto.h>
25
26BPF_HASH(currsock, u32, struct sock *);
27
28int kprobe__tcp_v4_connect(struct pt_regs *ctx, struct sock *sk)
29{
30 u32 pid = bpf_get_current_pid_tgid();
Brendan Gregg870b1cd2015-09-25 17:01:17 -070031
32 // stash the sock ptr for lookup on return
33 currsock.update(&pid, &sk);
34
35 return 0;
36};
37
38int kretprobe__tcp_v4_connect(struct pt_regs *ctx)
39{
40 int ret = ctx->ax;
41 u32 pid = bpf_get_current_pid_tgid();
42
43 struct sock **skpp;
44 skpp = currsock.lookup(&pid);
45 if (skpp == 0) {
46 return 0; // missed entry
47 }
48
Yonghong Song366eb2e2015-10-07 08:59:42 -070049 if (ret != 0) {
Brendan Greggf06d3b42015-10-15 17:21:32 -070050 // failed to send SYNC packet, may not have populated
51 // socket __sk_common.{skc_rcv_saddr, ...}
Yonghong Song366eb2e2015-10-07 08:59:42 -070052 currsock.delete(&pid);
53 return 0;
54 }
55
Brendan Gregg870b1cd2015-09-25 17:01:17 -070056 // pull in details
57 struct sock *skp = *skpp;
58 u32 saddr = 0, daddr = 0;
59 u16 dport = 0;
60 bpf_probe_read(&saddr, sizeof(saddr), &skp->__sk_common.skc_rcv_saddr);
61 bpf_probe_read(&daddr, sizeof(daddr), &skp->__sk_common.skc_daddr);
62 bpf_probe_read(&dport, sizeof(dport), &skp->__sk_common.skc_dport);
63
64 // output
65 bpf_trace_printk("%x %x %d\\n", saddr, daddr, ntohs(dport));
66
67 currsock.delete(&pid);
68
69 return 0;
70}
71"""
72
Brendan Gregg870b1cd2015-09-25 17:01:17 -070073# initialize BPF
74b = BPF(text=bpf_text)
75
76# header
Brendan Gregg870b1cd2015-09-25 17:01:17 -070077print("%-6s %-12s %-16s %-16s %-4s" % ("PID", "COMM", "SADDR", "DADDR",
78 "DPORT"))
79
Brendan Gregg870b1cd2015-09-25 17:01:17 -070080def inet_ntoa(addr):
81 dq = ''
82 for i in range(0, 4):
83 dq = dq + str(addr & 0xff)
84 if (i != 3):
85 dq = dq + '.'
86 addr = addr >> 8
87 return dq
88
89# format output
90while 1:
91 (task, pid, cpu, flags, ts, msg) = b.trace_fields()
92 (saddr_hs, daddr_hs, dport_s) = msg.split(" ")
93
Brendan Gregg870b1cd2015-09-25 17:01:17 -070094 print("%-6d %-12.12s %-16s %-16s %-4s" % (pid, task,
95 inet_ntoa(int(saddr_hs, 16)),
96 inet_ntoa(int(daddr_hs, 16)),
97 dport_s))