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