1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python 2*387f9dfdSAndroid Build Coastguard Worker# 3*387f9dfdSAndroid Build Coastguard Worker# tcpv4tracer Trace TCP connections. 4*387f9dfdSAndroid Build Coastguard Worker# For Linux, uses BCC, eBPF. Embedded C. 5*387f9dfdSAndroid Build Coastguard Worker# 6*387f9dfdSAndroid Build Coastguard Worker# USAGE: tcpv4tracer [-h] [-v] [-p PID] [-N NETNS] [-4 | -6] 7*387f9dfdSAndroid Build Coastguard Worker# 8*387f9dfdSAndroid Build Coastguard Worker# You should generally try to avoid writing long scripts that measure multiple 9*387f9dfdSAndroid Build Coastguard Worker# functions and walk multiple kernel structures, as they will be a burden to 10*387f9dfdSAndroid Build Coastguard Worker# maintain as the kernel changes. 11*387f9dfdSAndroid Build Coastguard Worker# The following code should be replaced, and simplified, when static TCP probes 12*387f9dfdSAndroid Build Coastguard Worker# exist. 13*387f9dfdSAndroid Build Coastguard Worker# 14*387f9dfdSAndroid Build Coastguard Worker# Copyright 2017-2020 Kinvolk GmbH 15*387f9dfdSAndroid Build Coastguard Worker# 16*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License") 17*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function 18*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF 19*387f9dfdSAndroid Build Coastguard Workerfrom bcc.containers import filter_by_containers 20*387f9dfdSAndroid Build Coastguard Worker 21*387f9dfdSAndroid Build Coastguard Workerimport argparse as ap 22*387f9dfdSAndroid Build Coastguard Workerfrom socket import inet_ntop, AF_INET, AF_INET6 23*387f9dfdSAndroid Build Coastguard Workerfrom struct import pack 24*387f9dfdSAndroid Build Coastguard Worker 25*387f9dfdSAndroid Build Coastguard Workerparser = ap.ArgumentParser(description="Trace TCP connections", 26*387f9dfdSAndroid Build Coastguard Worker formatter_class=ap.RawDescriptionHelpFormatter) 27*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--timestamp", action="store_true", 28*387f9dfdSAndroid Build Coastguard Worker help="include timestamp on output") 29*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", default=0, type=int, 30*387f9dfdSAndroid Build Coastguard Worker help="trace this PID only") 31*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-N", "--netns", default=0, type=int, 32*387f9dfdSAndroid Build Coastguard Worker help="trace this Network Namespace only") 33*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--cgroupmap", 34*387f9dfdSAndroid Build Coastguard Worker help="trace cgroups in this BPF map only") 35*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--mntnsmap", 36*387f9dfdSAndroid Build Coastguard Worker help="trace mount namespaces in this BPF map only") 37*387f9dfdSAndroid Build Coastguard Workergroup = parser.add_mutually_exclusive_group() 38*387f9dfdSAndroid Build Coastguard Workergroup.add_argument("-4", "--ipv4", action="store_true", 39*387f9dfdSAndroid Build Coastguard Worker help="trace IPv4 family only") 40*387f9dfdSAndroid Build Coastguard Workergroup.add_argument("-6", "--ipv6", action="store_true", 41*387f9dfdSAndroid Build Coastguard Worker help="trace IPv6 family only") 42*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-v", "--verbose", action="store_true", 43*387f9dfdSAndroid Build Coastguard Worker help="include Network Namespace in the output") 44*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true", 45*387f9dfdSAndroid Build Coastguard Worker help=ap.SUPPRESS) 46*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args() 47*387f9dfdSAndroid Build Coastguard Worker 48*387f9dfdSAndroid Build Coastguard Workerbpf_text = """ 49*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h> 50*387f9dfdSAndroid Build Coastguard Worker#pragma clang diagnostic push 51*387f9dfdSAndroid Build Coastguard Worker#pragma clang diagnostic ignored "-Wtautological-compare" 52*387f9dfdSAndroid Build Coastguard Worker#include <net/sock.h> 53*387f9dfdSAndroid Build Coastguard Worker#pragma clang diagnostic pop 54*387f9dfdSAndroid Build Coastguard Worker#include <net/inet_sock.h> 55*387f9dfdSAndroid Build Coastguard Worker#include <net/net_namespace.h> 56*387f9dfdSAndroid Build Coastguard Worker#include <bcc/proto.h> 57*387f9dfdSAndroid Build Coastguard Worker 58*387f9dfdSAndroid Build Coastguard Worker#define TCP_EVENT_TYPE_CONNECT 1 59*387f9dfdSAndroid Build Coastguard Worker#define TCP_EVENT_TYPE_ACCEPT 2 60*387f9dfdSAndroid Build Coastguard Worker#define TCP_EVENT_TYPE_CLOSE 3 61*387f9dfdSAndroid Build Coastguard Worker 62*387f9dfdSAndroid Build Coastguard Workerstruct tcp_ipv4_event_t { 63*387f9dfdSAndroid Build Coastguard Worker u64 ts_ns; 64*387f9dfdSAndroid Build Coastguard Worker u32 type; 65*387f9dfdSAndroid Build Coastguard Worker u32 pid; 66*387f9dfdSAndroid Build Coastguard Worker char comm[TASK_COMM_LEN]; 67*387f9dfdSAndroid Build Coastguard Worker u8 ip; 68*387f9dfdSAndroid Build Coastguard Worker u32 saddr; 69*387f9dfdSAndroid Build Coastguard Worker u32 daddr; 70*387f9dfdSAndroid Build Coastguard Worker u16 sport; 71*387f9dfdSAndroid Build Coastguard Worker u16 dport; 72*387f9dfdSAndroid Build Coastguard Worker u32 netns; 73*387f9dfdSAndroid Build Coastguard Worker}; 74*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(tcp_ipv4_event); 75*387f9dfdSAndroid Build Coastguard Worker 76*387f9dfdSAndroid Build Coastguard Workerstruct tcp_ipv6_event_t { 77*387f9dfdSAndroid Build Coastguard Worker u64 ts_ns; 78*387f9dfdSAndroid Build Coastguard Worker u32 type; 79*387f9dfdSAndroid Build Coastguard Worker u32 pid; 80*387f9dfdSAndroid Build Coastguard Worker char comm[TASK_COMM_LEN]; 81*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 saddr; 82*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 daddr; 83*387f9dfdSAndroid Build Coastguard Worker u16 sport; 84*387f9dfdSAndroid Build Coastguard Worker u16 dport; 85*387f9dfdSAndroid Build Coastguard Worker u32 netns; 86*387f9dfdSAndroid Build Coastguard Worker u8 ip; 87*387f9dfdSAndroid Build Coastguard Worker}; 88*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(tcp_ipv6_event); 89*387f9dfdSAndroid Build Coastguard Worker 90*387f9dfdSAndroid Build Coastguard Worker// tcp_set_state doesn't run in the context of the process that initiated the 91*387f9dfdSAndroid Build Coastguard Worker// connection so we need to store a map TUPLE -> PID to send the right PID on 92*387f9dfdSAndroid Build Coastguard Worker// the event 93*387f9dfdSAndroid Build Coastguard Workerstruct ipv4_tuple_t { 94*387f9dfdSAndroid Build Coastguard Worker u32 saddr; 95*387f9dfdSAndroid Build Coastguard Worker u32 daddr; 96*387f9dfdSAndroid Build Coastguard Worker u16 sport; 97*387f9dfdSAndroid Build Coastguard Worker u16 dport; 98*387f9dfdSAndroid Build Coastguard Worker u32 netns; 99*387f9dfdSAndroid Build Coastguard Worker}; 100*387f9dfdSAndroid Build Coastguard Worker 101*387f9dfdSAndroid Build Coastguard Workerstruct ipv6_tuple_t { 102*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 saddr; 103*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 daddr; 104*387f9dfdSAndroid Build Coastguard Worker u16 sport; 105*387f9dfdSAndroid Build Coastguard Worker u16 dport; 106*387f9dfdSAndroid Build Coastguard Worker u32 netns; 107*387f9dfdSAndroid Build Coastguard Worker}; 108*387f9dfdSAndroid Build Coastguard Worker 109*387f9dfdSAndroid Build Coastguard Workerstruct pid_comm_t { 110*387f9dfdSAndroid Build Coastguard Worker u64 pid; 111*387f9dfdSAndroid Build Coastguard Worker char comm[TASK_COMM_LEN]; 112*387f9dfdSAndroid Build Coastguard Worker}; 113*387f9dfdSAndroid Build Coastguard Worker 114*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(tuplepid_ipv4, struct ipv4_tuple_t, struct pid_comm_t); 115*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(tuplepid_ipv6, struct ipv6_tuple_t, struct pid_comm_t); 116*387f9dfdSAndroid Build Coastguard Worker 117*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(connectsock, u64, struct sock *); 118*387f9dfdSAndroid Build Coastguard Worker 119*387f9dfdSAndroid Build Coastguard Workerstatic int read_ipv4_tuple(struct ipv4_tuple_t *tuple, struct sock *skp) 120*387f9dfdSAndroid Build Coastguard Worker{ 121*387f9dfdSAndroid Build Coastguard Worker u32 net_ns_inum = 0; 122*387f9dfdSAndroid Build Coastguard Worker u32 saddr = skp->__sk_common.skc_rcv_saddr; 123*387f9dfdSAndroid Build Coastguard Worker u32 daddr = skp->__sk_common.skc_daddr; 124*387f9dfdSAndroid Build Coastguard Worker struct inet_sock *sockp = (struct inet_sock *)skp; 125*387f9dfdSAndroid Build Coastguard Worker u16 sport = sockp->inet_sport; 126*387f9dfdSAndroid Build Coastguard Worker u16 dport = skp->__sk_common.skc_dport; 127*387f9dfdSAndroid Build Coastguard Worker#ifdef CONFIG_NET_NS 128*387f9dfdSAndroid Build Coastguard Worker net_ns_inum = skp->__sk_common.skc_net.net->ns.inum; 129*387f9dfdSAndroid Build Coastguard Worker#endif 130*387f9dfdSAndroid Build Coastguard Worker 131*387f9dfdSAndroid Build Coastguard Worker ##FILTER_NETNS## 132*387f9dfdSAndroid Build Coastguard Worker 133*387f9dfdSAndroid Build Coastguard Worker tuple->saddr = saddr; 134*387f9dfdSAndroid Build Coastguard Worker tuple->daddr = daddr; 135*387f9dfdSAndroid Build Coastguard Worker tuple->sport = sport; 136*387f9dfdSAndroid Build Coastguard Worker tuple->dport = dport; 137*387f9dfdSAndroid Build Coastguard Worker tuple->netns = net_ns_inum; 138*387f9dfdSAndroid Build Coastguard Worker 139*387f9dfdSAndroid Build Coastguard Worker // if addresses or ports are 0, ignore 140*387f9dfdSAndroid Build Coastguard Worker if (saddr == 0 || daddr == 0 || sport == 0 || dport == 0) { 141*387f9dfdSAndroid Build Coastguard Worker return 0; 142*387f9dfdSAndroid Build Coastguard Worker } 143*387f9dfdSAndroid Build Coastguard Worker 144*387f9dfdSAndroid Build Coastguard Worker return 1; 145*387f9dfdSAndroid Build Coastguard Worker} 146*387f9dfdSAndroid Build Coastguard Worker 147*387f9dfdSAndroid Build Coastguard Workerstatic int read_ipv6_tuple(struct ipv6_tuple_t *tuple, struct sock *skp) 148*387f9dfdSAndroid Build Coastguard Worker{ 149*387f9dfdSAndroid Build Coastguard Worker u32 net_ns_inum = 0; 150*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 saddr = 0, daddr = 0; 151*387f9dfdSAndroid Build Coastguard Worker struct inet_sock *sockp = (struct inet_sock *)skp; 152*387f9dfdSAndroid Build Coastguard Worker u16 sport = sockp->inet_sport; 153*387f9dfdSAndroid Build Coastguard Worker u16 dport = skp->__sk_common.skc_dport; 154*387f9dfdSAndroid Build Coastguard Worker#ifdef CONFIG_NET_NS 155*387f9dfdSAndroid Build Coastguard Worker net_ns_inum = skp->__sk_common.skc_net.net->ns.inum; 156*387f9dfdSAndroid Build Coastguard Worker#endif 157*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&saddr, sizeof(saddr), 158*387f9dfdSAndroid Build Coastguard Worker skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); 159*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&daddr, sizeof(daddr), 160*387f9dfdSAndroid Build Coastguard Worker skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32); 161*387f9dfdSAndroid Build Coastguard Worker 162*387f9dfdSAndroid Build Coastguard Worker ##FILTER_NETNS## 163*387f9dfdSAndroid Build Coastguard Worker 164*387f9dfdSAndroid Build Coastguard Worker tuple->saddr = saddr; 165*387f9dfdSAndroid Build Coastguard Worker tuple->daddr = daddr; 166*387f9dfdSAndroid Build Coastguard Worker tuple->sport = sport; 167*387f9dfdSAndroid Build Coastguard Worker tuple->dport = dport; 168*387f9dfdSAndroid Build Coastguard Worker tuple->netns = net_ns_inum; 169*387f9dfdSAndroid Build Coastguard Worker 170*387f9dfdSAndroid Build Coastguard Worker // if addresses or ports are 0, ignore 171*387f9dfdSAndroid Build Coastguard Worker if (saddr == 0 || daddr == 0 || sport == 0 || dport == 0) { 172*387f9dfdSAndroid Build Coastguard Worker return 0; 173*387f9dfdSAndroid Build Coastguard Worker } 174*387f9dfdSAndroid Build Coastguard Worker 175*387f9dfdSAndroid Build Coastguard Worker return 1; 176*387f9dfdSAndroid Build Coastguard Worker} 177*387f9dfdSAndroid Build Coastguard Worker 178*387f9dfdSAndroid Build Coastguard Workerstatic bool check_family(struct sock *sk, u16 expected_family) { 179*387f9dfdSAndroid Build Coastguard Worker u64 zero = 0; 180*387f9dfdSAndroid Build Coastguard Worker u16 family = sk->__sk_common.skc_family; 181*387f9dfdSAndroid Build Coastguard Worker return family == expected_family; 182*387f9dfdSAndroid Build Coastguard Worker} 183*387f9dfdSAndroid Build Coastguard Worker 184*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v4_entry(struct pt_regs *ctx, struct sock *sk) 185*387f9dfdSAndroid Build Coastguard Worker{ 186*387f9dfdSAndroid Build Coastguard Worker if (container_should_be_filtered()) { 187*387f9dfdSAndroid Build Coastguard Worker return 0; 188*387f9dfdSAndroid Build Coastguard Worker } 189*387f9dfdSAndroid Build Coastguard Worker 190*387f9dfdSAndroid Build Coastguard Worker u64 pid = bpf_get_current_pid_tgid(); 191*387f9dfdSAndroid Build Coastguard Worker 192*387f9dfdSAndroid Build Coastguard Worker ##FILTER_PID## 193*387f9dfdSAndroid Build Coastguard Worker 194*387f9dfdSAndroid Build Coastguard Worker u16 family = sk->__sk_common.skc_family; 195*387f9dfdSAndroid Build Coastguard Worker ##FILTER_FAMILY## 196*387f9dfdSAndroid Build Coastguard Worker 197*387f9dfdSAndroid Build Coastguard Worker 198*387f9dfdSAndroid Build Coastguard Worker // stash the sock ptr for lookup on return 199*387f9dfdSAndroid Build Coastguard Worker connectsock.update(&pid, &sk); 200*387f9dfdSAndroid Build Coastguard Worker 201*387f9dfdSAndroid Build Coastguard Worker return 0; 202*387f9dfdSAndroid Build Coastguard Worker} 203*387f9dfdSAndroid Build Coastguard Worker 204*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v4_return(struct pt_regs *ctx) 205*387f9dfdSAndroid Build Coastguard Worker{ 206*387f9dfdSAndroid Build Coastguard Worker int ret = PT_REGS_RC(ctx); 207*387f9dfdSAndroid Build Coastguard Worker u64 pid = bpf_get_current_pid_tgid(); 208*387f9dfdSAndroid Build Coastguard Worker 209*387f9dfdSAndroid Build Coastguard Worker struct sock **skpp; 210*387f9dfdSAndroid Build Coastguard Worker skpp = connectsock.lookup(&pid); 211*387f9dfdSAndroid Build Coastguard Worker if (skpp == 0) { 212*387f9dfdSAndroid Build Coastguard Worker return 0; // missed entry 213*387f9dfdSAndroid Build Coastguard Worker } 214*387f9dfdSAndroid Build Coastguard Worker 215*387f9dfdSAndroid Build Coastguard Worker connectsock.delete(&pid); 216*387f9dfdSAndroid Build Coastguard Worker 217*387f9dfdSAndroid Build Coastguard Worker if (ret != 0) { 218*387f9dfdSAndroid Build Coastguard Worker // failed to send SYNC packet, may not have populated 219*387f9dfdSAndroid Build Coastguard Worker // socket __sk_common.{skc_rcv_saddr, ...} 220*387f9dfdSAndroid Build Coastguard Worker return 0; 221*387f9dfdSAndroid Build Coastguard Worker } 222*387f9dfdSAndroid Build Coastguard Worker 223*387f9dfdSAndroid Build Coastguard Worker // pull in details 224*387f9dfdSAndroid Build Coastguard Worker struct sock *skp = *skpp; 225*387f9dfdSAndroid Build Coastguard Worker struct ipv4_tuple_t t = { }; 226*387f9dfdSAndroid Build Coastguard Worker if (!read_ipv4_tuple(&t, skp)) { 227*387f9dfdSAndroid Build Coastguard Worker return 0; 228*387f9dfdSAndroid Build Coastguard Worker } 229*387f9dfdSAndroid Build Coastguard Worker 230*387f9dfdSAndroid Build Coastguard Worker struct pid_comm_t p = { }; 231*387f9dfdSAndroid Build Coastguard Worker p.pid = pid; 232*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&p.comm, sizeof(p.comm)); 233*387f9dfdSAndroid Build Coastguard Worker 234*387f9dfdSAndroid Build Coastguard Worker tuplepid_ipv4.update(&t, &p); 235*387f9dfdSAndroid Build Coastguard Worker 236*387f9dfdSAndroid Build Coastguard Worker return 0; 237*387f9dfdSAndroid Build Coastguard Worker} 238*387f9dfdSAndroid Build Coastguard Worker 239*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v6_entry(struct pt_regs *ctx, struct sock *sk) 240*387f9dfdSAndroid Build Coastguard Worker{ 241*387f9dfdSAndroid Build Coastguard Worker if (container_should_be_filtered()) { 242*387f9dfdSAndroid Build Coastguard Worker return 0; 243*387f9dfdSAndroid Build Coastguard Worker } 244*387f9dfdSAndroid Build Coastguard Worker u64 pid = bpf_get_current_pid_tgid(); 245*387f9dfdSAndroid Build Coastguard Worker 246*387f9dfdSAndroid Build Coastguard Worker ##FILTER_PID## 247*387f9dfdSAndroid Build Coastguard Worker u16 family = sk->__sk_common.skc_family; 248*387f9dfdSAndroid Build Coastguard Worker ##FILTER_FAMILY## 249*387f9dfdSAndroid Build Coastguard Worker 250*387f9dfdSAndroid Build Coastguard Worker // stash the sock ptr for lookup on return 251*387f9dfdSAndroid Build Coastguard Worker connectsock.update(&pid, &sk); 252*387f9dfdSAndroid Build Coastguard Worker 253*387f9dfdSAndroid Build Coastguard Worker return 0; 254*387f9dfdSAndroid Build Coastguard Worker} 255*387f9dfdSAndroid Build Coastguard Worker 256*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v6_return(struct pt_regs *ctx) 257*387f9dfdSAndroid Build Coastguard Worker{ 258*387f9dfdSAndroid Build Coastguard Worker int ret = PT_REGS_RC(ctx); 259*387f9dfdSAndroid Build Coastguard Worker u64 pid = bpf_get_current_pid_tgid(); 260*387f9dfdSAndroid Build Coastguard Worker 261*387f9dfdSAndroid Build Coastguard Worker struct sock **skpp; 262*387f9dfdSAndroid Build Coastguard Worker skpp = connectsock.lookup(&pid); 263*387f9dfdSAndroid Build Coastguard Worker if (skpp == 0) { 264*387f9dfdSAndroid Build Coastguard Worker return 0; // missed entry 265*387f9dfdSAndroid Build Coastguard Worker } 266*387f9dfdSAndroid Build Coastguard Worker 267*387f9dfdSAndroid Build Coastguard Worker connectsock.delete(&pid); 268*387f9dfdSAndroid Build Coastguard Worker 269*387f9dfdSAndroid Build Coastguard Worker if (ret != 0) { 270*387f9dfdSAndroid Build Coastguard Worker // failed to send SYNC packet, may not have populated 271*387f9dfdSAndroid Build Coastguard Worker // socket __sk_common.{skc_rcv_saddr, ...} 272*387f9dfdSAndroid Build Coastguard Worker return 0; 273*387f9dfdSAndroid Build Coastguard Worker } 274*387f9dfdSAndroid Build Coastguard Worker 275*387f9dfdSAndroid Build Coastguard Worker // pull in details 276*387f9dfdSAndroid Build Coastguard Worker struct sock *skp = *skpp; 277*387f9dfdSAndroid Build Coastguard Worker struct ipv6_tuple_t t = { }; 278*387f9dfdSAndroid Build Coastguard Worker if (!read_ipv6_tuple(&t, skp)) { 279*387f9dfdSAndroid Build Coastguard Worker return 0; 280*387f9dfdSAndroid Build Coastguard Worker } 281*387f9dfdSAndroid Build Coastguard Worker 282*387f9dfdSAndroid Build Coastguard Worker struct pid_comm_t p = { }; 283*387f9dfdSAndroid Build Coastguard Worker p.pid = pid; 284*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&p.comm, sizeof(p.comm)); 285*387f9dfdSAndroid Build Coastguard Worker 286*387f9dfdSAndroid Build Coastguard Worker tuplepid_ipv6.update(&t, &p); 287*387f9dfdSAndroid Build Coastguard Worker 288*387f9dfdSAndroid Build Coastguard Worker return 0; 289*387f9dfdSAndroid Build Coastguard Worker} 290*387f9dfdSAndroid Build Coastguard Worker 291*387f9dfdSAndroid Build Coastguard Workerint trace_tcp_set_state_entry(struct pt_regs *ctx, struct sock *skp, int state) 292*387f9dfdSAndroid Build Coastguard Worker{ 293*387f9dfdSAndroid Build Coastguard Worker if (state != TCP_ESTABLISHED && state != TCP_CLOSE) { 294*387f9dfdSAndroid Build Coastguard Worker return 0; 295*387f9dfdSAndroid Build Coastguard Worker } 296*387f9dfdSAndroid Build Coastguard Worker 297*387f9dfdSAndroid Build Coastguard Worker u16 family = skp->__sk_common.skc_family; 298*387f9dfdSAndroid Build Coastguard Worker ##FILTER_FAMILY## 299*387f9dfdSAndroid Build Coastguard Worker 300*387f9dfdSAndroid Build Coastguard Worker u8 ipver = 0; 301*387f9dfdSAndroid Build Coastguard Worker if (check_family(skp, AF_INET)) { 302*387f9dfdSAndroid Build Coastguard Worker ipver = 4; 303*387f9dfdSAndroid Build Coastguard Worker struct ipv4_tuple_t t = { }; 304*387f9dfdSAndroid Build Coastguard Worker if (!read_ipv4_tuple(&t, skp)) { 305*387f9dfdSAndroid Build Coastguard Worker return 0; 306*387f9dfdSAndroid Build Coastguard Worker } 307*387f9dfdSAndroid Build Coastguard Worker 308*387f9dfdSAndroid Build Coastguard Worker if (state == TCP_CLOSE) { 309*387f9dfdSAndroid Build Coastguard Worker tuplepid_ipv4.delete(&t); 310*387f9dfdSAndroid Build Coastguard Worker return 0; 311*387f9dfdSAndroid Build Coastguard Worker } 312*387f9dfdSAndroid Build Coastguard Worker 313*387f9dfdSAndroid Build Coastguard Worker struct pid_comm_t *p; 314*387f9dfdSAndroid Build Coastguard Worker p = tuplepid_ipv4.lookup(&t); 315*387f9dfdSAndroid Build Coastguard Worker if (p == 0) { 316*387f9dfdSAndroid Build Coastguard Worker return 0; // missed entry 317*387f9dfdSAndroid Build Coastguard Worker } 318*387f9dfdSAndroid Build Coastguard Worker 319*387f9dfdSAndroid Build Coastguard Worker struct tcp_ipv4_event_t evt4 = { }; 320*387f9dfdSAndroid Build Coastguard Worker evt4.ts_ns = bpf_ktime_get_ns(); 321*387f9dfdSAndroid Build Coastguard Worker evt4.type = TCP_EVENT_TYPE_CONNECT; 322*387f9dfdSAndroid Build Coastguard Worker evt4.pid = p->pid >> 32; 323*387f9dfdSAndroid Build Coastguard Worker evt4.ip = ipver; 324*387f9dfdSAndroid Build Coastguard Worker evt4.saddr = t.saddr; 325*387f9dfdSAndroid Build Coastguard Worker evt4.daddr = t.daddr; 326*387f9dfdSAndroid Build Coastguard Worker evt4.sport = ntohs(t.sport); 327*387f9dfdSAndroid Build Coastguard Worker evt4.dport = ntohs(t.dport); 328*387f9dfdSAndroid Build Coastguard Worker evt4.netns = t.netns; 329*387f9dfdSAndroid Build Coastguard Worker 330*387f9dfdSAndroid Build Coastguard Worker int i; 331*387f9dfdSAndroid Build Coastguard Worker for (i = 0; i < TASK_COMM_LEN; i++) { 332*387f9dfdSAndroid Build Coastguard Worker evt4.comm[i] = p->comm[i]; 333*387f9dfdSAndroid Build Coastguard Worker } 334*387f9dfdSAndroid Build Coastguard Worker 335*387f9dfdSAndroid Build Coastguard Worker tcp_ipv4_event.perf_submit(ctx, &evt4, sizeof(evt4)); 336*387f9dfdSAndroid Build Coastguard Worker tuplepid_ipv4.delete(&t); 337*387f9dfdSAndroid Build Coastguard Worker } else if (check_family(skp, AF_INET6)) { 338*387f9dfdSAndroid Build Coastguard Worker ipver = 6; 339*387f9dfdSAndroid Build Coastguard Worker struct ipv6_tuple_t t = { }; 340*387f9dfdSAndroid Build Coastguard Worker if (!read_ipv6_tuple(&t, skp)) { 341*387f9dfdSAndroid Build Coastguard Worker return 0; 342*387f9dfdSAndroid Build Coastguard Worker } 343*387f9dfdSAndroid Build Coastguard Worker 344*387f9dfdSAndroid Build Coastguard Worker if (state == TCP_CLOSE) { 345*387f9dfdSAndroid Build Coastguard Worker tuplepid_ipv6.delete(&t); 346*387f9dfdSAndroid Build Coastguard Worker return 0; 347*387f9dfdSAndroid Build Coastguard Worker } 348*387f9dfdSAndroid Build Coastguard Worker 349*387f9dfdSAndroid Build Coastguard Worker struct pid_comm_t *p; 350*387f9dfdSAndroid Build Coastguard Worker p = tuplepid_ipv6.lookup(&t); 351*387f9dfdSAndroid Build Coastguard Worker if (p == 0) { 352*387f9dfdSAndroid Build Coastguard Worker return 0; // missed entry 353*387f9dfdSAndroid Build Coastguard Worker } 354*387f9dfdSAndroid Build Coastguard Worker 355*387f9dfdSAndroid Build Coastguard Worker struct tcp_ipv6_event_t evt6 = { }; 356*387f9dfdSAndroid Build Coastguard Worker evt6.ts_ns = bpf_ktime_get_ns(); 357*387f9dfdSAndroid Build Coastguard Worker evt6.type = TCP_EVENT_TYPE_CONNECT; 358*387f9dfdSAndroid Build Coastguard Worker evt6.pid = p->pid >> 32; 359*387f9dfdSAndroid Build Coastguard Worker evt6.ip = ipver; 360*387f9dfdSAndroid Build Coastguard Worker evt6.saddr = t.saddr; 361*387f9dfdSAndroid Build Coastguard Worker evt6.daddr = t.daddr; 362*387f9dfdSAndroid Build Coastguard Worker evt6.sport = ntohs(t.sport); 363*387f9dfdSAndroid Build Coastguard Worker evt6.dport = ntohs(t.dport); 364*387f9dfdSAndroid Build Coastguard Worker evt6.netns = t.netns; 365*387f9dfdSAndroid Build Coastguard Worker 366*387f9dfdSAndroid Build Coastguard Worker int i; 367*387f9dfdSAndroid Build Coastguard Worker for (i = 0; i < TASK_COMM_LEN; i++) { 368*387f9dfdSAndroid Build Coastguard Worker evt6.comm[i] = p->comm[i]; 369*387f9dfdSAndroid Build Coastguard Worker } 370*387f9dfdSAndroid Build Coastguard Worker 371*387f9dfdSAndroid Build Coastguard Worker tcp_ipv6_event.perf_submit(ctx, &evt6, sizeof(evt6)); 372*387f9dfdSAndroid Build Coastguard Worker tuplepid_ipv6.delete(&t); 373*387f9dfdSAndroid Build Coastguard Worker } 374*387f9dfdSAndroid Build Coastguard Worker // else drop 375*387f9dfdSAndroid Build Coastguard Worker 376*387f9dfdSAndroid Build Coastguard Worker return 0; 377*387f9dfdSAndroid Build Coastguard Worker} 378*387f9dfdSAndroid Build Coastguard Worker 379*387f9dfdSAndroid Build Coastguard Workerint trace_close_entry(struct pt_regs *ctx, struct sock *skp) 380*387f9dfdSAndroid Build Coastguard Worker{ 381*387f9dfdSAndroid Build Coastguard Worker if (container_should_be_filtered()) { 382*387f9dfdSAndroid Build Coastguard Worker return 0; 383*387f9dfdSAndroid Build Coastguard Worker } 384*387f9dfdSAndroid Build Coastguard Worker 385*387f9dfdSAndroid Build Coastguard Worker u64 pid = bpf_get_current_pid_tgid(); 386*387f9dfdSAndroid Build Coastguard Worker 387*387f9dfdSAndroid Build Coastguard Worker ##FILTER_PID## 388*387f9dfdSAndroid Build Coastguard Worker 389*387f9dfdSAndroid Build Coastguard Worker u16 family = skp->__sk_common.skc_family; 390*387f9dfdSAndroid Build Coastguard Worker ##FILTER_FAMILY## 391*387f9dfdSAndroid Build Coastguard Worker 392*387f9dfdSAndroid Build Coastguard Worker u8 oldstate = skp->sk_state; 393*387f9dfdSAndroid Build Coastguard Worker // Don't generate close events for connections that were never 394*387f9dfdSAndroid Build Coastguard Worker // established in the first place. 395*387f9dfdSAndroid Build Coastguard Worker if (oldstate == TCP_SYN_SENT || 396*387f9dfdSAndroid Build Coastguard Worker oldstate == TCP_SYN_RECV || 397*387f9dfdSAndroid Build Coastguard Worker oldstate == TCP_NEW_SYN_RECV) 398*387f9dfdSAndroid Build Coastguard Worker return 0; 399*387f9dfdSAndroid Build Coastguard Worker 400*387f9dfdSAndroid Build Coastguard Worker u8 ipver = 0; 401*387f9dfdSAndroid Build Coastguard Worker if (check_family(skp, AF_INET)) { 402*387f9dfdSAndroid Build Coastguard Worker ipver = 4; 403*387f9dfdSAndroid Build Coastguard Worker struct ipv4_tuple_t t = { }; 404*387f9dfdSAndroid Build Coastguard Worker if (!read_ipv4_tuple(&t, skp)) { 405*387f9dfdSAndroid Build Coastguard Worker return 0; 406*387f9dfdSAndroid Build Coastguard Worker } 407*387f9dfdSAndroid Build Coastguard Worker 408*387f9dfdSAndroid Build Coastguard Worker struct tcp_ipv4_event_t evt4 = { }; 409*387f9dfdSAndroid Build Coastguard Worker evt4.ts_ns = bpf_ktime_get_ns(); 410*387f9dfdSAndroid Build Coastguard Worker evt4.type = TCP_EVENT_TYPE_CLOSE; 411*387f9dfdSAndroid Build Coastguard Worker evt4.pid = pid >> 32; 412*387f9dfdSAndroid Build Coastguard Worker evt4.ip = ipver; 413*387f9dfdSAndroid Build Coastguard Worker evt4.saddr = t.saddr; 414*387f9dfdSAndroid Build Coastguard Worker evt4.daddr = t.daddr; 415*387f9dfdSAndroid Build Coastguard Worker evt4.sport = ntohs(t.sport); 416*387f9dfdSAndroid Build Coastguard Worker evt4.dport = ntohs(t.dport); 417*387f9dfdSAndroid Build Coastguard Worker evt4.netns = t.netns; 418*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&evt4.comm, sizeof(evt4.comm)); 419*387f9dfdSAndroid Build Coastguard Worker 420*387f9dfdSAndroid Build Coastguard Worker tcp_ipv4_event.perf_submit(ctx, &evt4, sizeof(evt4)); 421*387f9dfdSAndroid Build Coastguard Worker } else if (check_family(skp, AF_INET6)) { 422*387f9dfdSAndroid Build Coastguard Worker ipver = 6; 423*387f9dfdSAndroid Build Coastguard Worker struct ipv6_tuple_t t = { }; 424*387f9dfdSAndroid Build Coastguard Worker if (!read_ipv6_tuple(&t, skp)) { 425*387f9dfdSAndroid Build Coastguard Worker return 0; 426*387f9dfdSAndroid Build Coastguard Worker } 427*387f9dfdSAndroid Build Coastguard Worker 428*387f9dfdSAndroid Build Coastguard Worker struct tcp_ipv6_event_t evt6 = { }; 429*387f9dfdSAndroid Build Coastguard Worker evt6.ts_ns = bpf_ktime_get_ns(); 430*387f9dfdSAndroid Build Coastguard Worker evt6.type = TCP_EVENT_TYPE_CLOSE; 431*387f9dfdSAndroid Build Coastguard Worker evt6.pid = pid >> 32; 432*387f9dfdSAndroid Build Coastguard Worker evt6.ip = ipver; 433*387f9dfdSAndroid Build Coastguard Worker evt6.saddr = t.saddr; 434*387f9dfdSAndroid Build Coastguard Worker evt6.daddr = t.daddr; 435*387f9dfdSAndroid Build Coastguard Worker evt6.sport = ntohs(t.sport); 436*387f9dfdSAndroid Build Coastguard Worker evt6.dport = ntohs(t.dport); 437*387f9dfdSAndroid Build Coastguard Worker evt6.netns = t.netns; 438*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&evt6.comm, sizeof(evt6.comm)); 439*387f9dfdSAndroid Build Coastguard Worker 440*387f9dfdSAndroid Build Coastguard Worker tcp_ipv6_event.perf_submit(ctx, &evt6, sizeof(evt6)); 441*387f9dfdSAndroid Build Coastguard Worker } 442*387f9dfdSAndroid Build Coastguard Worker // else drop 443*387f9dfdSAndroid Build Coastguard Worker 444*387f9dfdSAndroid Build Coastguard Worker return 0; 445*387f9dfdSAndroid Build Coastguard Worker}; 446*387f9dfdSAndroid Build Coastguard Worker 447*387f9dfdSAndroid Build Coastguard Workerint trace_accept_return(struct pt_regs *ctx) 448*387f9dfdSAndroid Build Coastguard Worker{ 449*387f9dfdSAndroid Build Coastguard Worker if (container_should_be_filtered()) { 450*387f9dfdSAndroid Build Coastguard Worker return 0; 451*387f9dfdSAndroid Build Coastguard Worker } 452*387f9dfdSAndroid Build Coastguard Worker 453*387f9dfdSAndroid Build Coastguard Worker struct sock *newsk = (struct sock *)PT_REGS_RC(ctx); 454*387f9dfdSAndroid Build Coastguard Worker u64 pid = bpf_get_current_pid_tgid(); 455*387f9dfdSAndroid Build Coastguard Worker 456*387f9dfdSAndroid Build Coastguard Worker ##FILTER_PID## 457*387f9dfdSAndroid Build Coastguard Worker 458*387f9dfdSAndroid Build Coastguard Worker if (newsk == NULL) { 459*387f9dfdSAndroid Build Coastguard Worker return 0; 460*387f9dfdSAndroid Build Coastguard Worker } 461*387f9dfdSAndroid Build Coastguard Worker 462*387f9dfdSAndroid Build Coastguard Worker // pull in details 463*387f9dfdSAndroid Build Coastguard Worker u16 lport = 0, dport = 0; 464*387f9dfdSAndroid Build Coastguard Worker u32 net_ns_inum = 0; 465*387f9dfdSAndroid Build Coastguard Worker u8 ipver = 0; 466*387f9dfdSAndroid Build Coastguard Worker 467*387f9dfdSAndroid Build Coastguard Worker dport = newsk->__sk_common.skc_dport; 468*387f9dfdSAndroid Build Coastguard Worker lport = newsk->__sk_common.skc_num; 469*387f9dfdSAndroid Build Coastguard Worker 470*387f9dfdSAndroid Build Coastguard Worker // Get network namespace id, if kernel supports it 471*387f9dfdSAndroid Build Coastguard Worker#ifdef CONFIG_NET_NS 472*387f9dfdSAndroid Build Coastguard Worker net_ns_inum = newsk->__sk_common.skc_net.net->ns.inum; 473*387f9dfdSAndroid Build Coastguard Worker#endif 474*387f9dfdSAndroid Build Coastguard Worker 475*387f9dfdSAndroid Build Coastguard Worker ##FILTER_NETNS## 476*387f9dfdSAndroid Build Coastguard Worker 477*387f9dfdSAndroid Build Coastguard Worker u16 family = newsk->__sk_common.skc_family; 478*387f9dfdSAndroid Build Coastguard Worker ##FILTER_FAMILY## 479*387f9dfdSAndroid Build Coastguard Worker 480*387f9dfdSAndroid Build Coastguard Worker if (check_family(newsk, AF_INET)) { 481*387f9dfdSAndroid Build Coastguard Worker ipver = 4; 482*387f9dfdSAndroid Build Coastguard Worker 483*387f9dfdSAndroid Build Coastguard Worker struct tcp_ipv4_event_t evt4 = { 0 }; 484*387f9dfdSAndroid Build Coastguard Worker 485*387f9dfdSAndroid Build Coastguard Worker evt4.ts_ns = bpf_ktime_get_ns(); 486*387f9dfdSAndroid Build Coastguard Worker evt4.type = TCP_EVENT_TYPE_ACCEPT; 487*387f9dfdSAndroid Build Coastguard Worker evt4.netns = net_ns_inum; 488*387f9dfdSAndroid Build Coastguard Worker evt4.pid = pid >> 32; 489*387f9dfdSAndroid Build Coastguard Worker evt4.ip = ipver; 490*387f9dfdSAndroid Build Coastguard Worker 491*387f9dfdSAndroid Build Coastguard Worker evt4.saddr = newsk->__sk_common.skc_rcv_saddr; 492*387f9dfdSAndroid Build Coastguard Worker evt4.daddr = newsk->__sk_common.skc_daddr; 493*387f9dfdSAndroid Build Coastguard Worker 494*387f9dfdSAndroid Build Coastguard Worker evt4.sport = lport; 495*387f9dfdSAndroid Build Coastguard Worker evt4.dport = ntohs(dport); 496*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&evt4.comm, sizeof(evt4.comm)); 497*387f9dfdSAndroid Build Coastguard Worker 498*387f9dfdSAndroid Build Coastguard Worker // do not send event if IP address is 0.0.0.0 or port is 0 499*387f9dfdSAndroid Build Coastguard Worker if (evt4.saddr != 0 && evt4.daddr != 0 && 500*387f9dfdSAndroid Build Coastguard Worker evt4.sport != 0 && evt4.dport != 0) { 501*387f9dfdSAndroid Build Coastguard Worker tcp_ipv4_event.perf_submit(ctx, &evt4, sizeof(evt4)); 502*387f9dfdSAndroid Build Coastguard Worker } 503*387f9dfdSAndroid Build Coastguard Worker } else if (check_family(newsk, AF_INET6)) { 504*387f9dfdSAndroid Build Coastguard Worker ipver = 6; 505*387f9dfdSAndroid Build Coastguard Worker 506*387f9dfdSAndroid Build Coastguard Worker struct tcp_ipv6_event_t evt6 = { 0 }; 507*387f9dfdSAndroid Build Coastguard Worker 508*387f9dfdSAndroid Build Coastguard Worker evt6.ts_ns = bpf_ktime_get_ns(); 509*387f9dfdSAndroid Build Coastguard Worker evt6.type = TCP_EVENT_TYPE_ACCEPT; 510*387f9dfdSAndroid Build Coastguard Worker evt6.netns = net_ns_inum; 511*387f9dfdSAndroid Build Coastguard Worker evt6.pid = pid >> 32; 512*387f9dfdSAndroid Build Coastguard Worker evt6.ip = ipver; 513*387f9dfdSAndroid Build Coastguard Worker 514*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&evt6.saddr, sizeof(evt6.saddr), 515*387f9dfdSAndroid Build Coastguard Worker newsk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); 516*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&evt6.daddr, sizeof(evt6.daddr), 517*387f9dfdSAndroid Build Coastguard Worker newsk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); 518*387f9dfdSAndroid Build Coastguard Worker 519*387f9dfdSAndroid Build Coastguard Worker evt6.sport = lport; 520*387f9dfdSAndroid Build Coastguard Worker evt6.dport = ntohs(dport); 521*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&evt6.comm, sizeof(evt6.comm)); 522*387f9dfdSAndroid Build Coastguard Worker 523*387f9dfdSAndroid Build Coastguard Worker // do not send event if IP address is 0.0.0.0 or port is 0 524*387f9dfdSAndroid Build Coastguard Worker if (evt6.saddr != 0 && evt6.daddr != 0 && 525*387f9dfdSAndroid Build Coastguard Worker evt6.sport != 0 && evt6.dport != 0) { 526*387f9dfdSAndroid Build Coastguard Worker tcp_ipv6_event.perf_submit(ctx, &evt6, sizeof(evt6)); 527*387f9dfdSAndroid Build Coastguard Worker } 528*387f9dfdSAndroid Build Coastguard Worker } 529*387f9dfdSAndroid Build Coastguard Worker // else drop 530*387f9dfdSAndroid Build Coastguard Worker 531*387f9dfdSAndroid Build Coastguard Worker return 0; 532*387f9dfdSAndroid Build Coastguard Worker} 533*387f9dfdSAndroid Build Coastguard Worker""" 534*387f9dfdSAndroid Build Coastguard Worker 535*387f9dfdSAndroid Build Coastguard Workerverbose_types = {"C": "connect", "A": "accept", 536*387f9dfdSAndroid Build Coastguard Worker "X": "close", "U": "unknown"} 537*387f9dfdSAndroid Build Coastguard Worker 538*387f9dfdSAndroid Build Coastguard Worker 539*387f9dfdSAndroid Build Coastguard Workerdef print_ipv4_event(cpu, data, size): 540*387f9dfdSAndroid Build Coastguard Worker event = b["tcp_ipv4_event"].event(data) 541*387f9dfdSAndroid Build Coastguard Worker global start_ts 542*387f9dfdSAndroid Build Coastguard Worker 543*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 544*387f9dfdSAndroid Build Coastguard Worker if start_ts == 0: 545*387f9dfdSAndroid Build Coastguard Worker start_ts = event.ts_ns 546*387f9dfdSAndroid Build Coastguard Worker if args.verbose: 547*387f9dfdSAndroid Build Coastguard Worker print("%-14d" % (event.ts_ns - start_ts), end="") 548*387f9dfdSAndroid Build Coastguard Worker else: 549*387f9dfdSAndroid Build Coastguard Worker print("%-9.3f" % ((event.ts_ns - start_ts) / 1000000000.0), end="") 550*387f9dfdSAndroid Build Coastguard Worker if event.type == 1: 551*387f9dfdSAndroid Build Coastguard Worker type_str = "C" 552*387f9dfdSAndroid Build Coastguard Worker elif event.type == 2: 553*387f9dfdSAndroid Build Coastguard Worker type_str = "A" 554*387f9dfdSAndroid Build Coastguard Worker elif event.type == 3: 555*387f9dfdSAndroid Build Coastguard Worker type_str = "X" 556*387f9dfdSAndroid Build Coastguard Worker else: 557*387f9dfdSAndroid Build Coastguard Worker type_str = "U" 558*387f9dfdSAndroid Build Coastguard Worker 559*387f9dfdSAndroid Build Coastguard Worker if args.verbose: 560*387f9dfdSAndroid Build Coastguard Worker print("%-12s " % (verbose_types[type_str]), end="") 561*387f9dfdSAndroid Build Coastguard Worker else: 562*387f9dfdSAndroid Build Coastguard Worker print("%-2s " % (type_str), end="") 563*387f9dfdSAndroid Build Coastguard Worker 564*387f9dfdSAndroid Build Coastguard Worker print("%-6d %-16s %-2d %-16s %-16s %-6d %-6d" % 565*387f9dfdSAndroid Build Coastguard Worker (event.pid, event.comm.decode('utf-8', 'replace'), 566*387f9dfdSAndroid Build Coastguard Worker event.ip, 567*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack("I", event.saddr)), 568*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack("I", event.daddr)), 569*387f9dfdSAndroid Build Coastguard Worker event.sport, 570*387f9dfdSAndroid Build Coastguard Worker event.dport), end="") 571*387f9dfdSAndroid Build Coastguard Worker if args.verbose and not args.netns: 572*387f9dfdSAndroid Build Coastguard Worker print(" %-8d" % event.netns) 573*387f9dfdSAndroid Build Coastguard Worker else: 574*387f9dfdSAndroid Build Coastguard Worker print() 575*387f9dfdSAndroid Build Coastguard Worker 576*387f9dfdSAndroid Build Coastguard Worker 577*387f9dfdSAndroid Build Coastguard Workerdef print_ipv6_event(cpu, data, size): 578*387f9dfdSAndroid Build Coastguard Worker event = b["tcp_ipv6_event"].event(data) 579*387f9dfdSAndroid Build Coastguard Worker global start_ts 580*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 581*387f9dfdSAndroid Build Coastguard Worker if start_ts == 0: 582*387f9dfdSAndroid Build Coastguard Worker start_ts = event.ts_ns 583*387f9dfdSAndroid Build Coastguard Worker if args.verbose: 584*387f9dfdSAndroid Build Coastguard Worker print("%-14d" % (event.ts_ns - start_ts), end="") 585*387f9dfdSAndroid Build Coastguard Worker else: 586*387f9dfdSAndroid Build Coastguard Worker print("%-9.3f" % ((event.ts_ns - start_ts) / 1000000000.0), end="") 587*387f9dfdSAndroid Build Coastguard Worker if event.type == 1: 588*387f9dfdSAndroid Build Coastguard Worker type_str = "C" 589*387f9dfdSAndroid Build Coastguard Worker elif event.type == 2: 590*387f9dfdSAndroid Build Coastguard Worker type_str = "A" 591*387f9dfdSAndroid Build Coastguard Worker elif event.type == 3: 592*387f9dfdSAndroid Build Coastguard Worker type_str = "X" 593*387f9dfdSAndroid Build Coastguard Worker else: 594*387f9dfdSAndroid Build Coastguard Worker type_str = "U" 595*387f9dfdSAndroid Build Coastguard Worker 596*387f9dfdSAndroid Build Coastguard Worker if args.verbose: 597*387f9dfdSAndroid Build Coastguard Worker print("%-12s " % (verbose_types[type_str]), end="") 598*387f9dfdSAndroid Build Coastguard Worker else: 599*387f9dfdSAndroid Build Coastguard Worker print("%-2s " % (type_str), end="") 600*387f9dfdSAndroid Build Coastguard Worker 601*387f9dfdSAndroid Build Coastguard Worker print("%-6d %-16s %-2d %-16s %-16s %-6d %-6d" % 602*387f9dfdSAndroid Build Coastguard Worker (event.pid, event.comm.decode('utf-8', 'replace'), 603*387f9dfdSAndroid Build Coastguard Worker event.ip, 604*387f9dfdSAndroid Build Coastguard Worker "[" + inet_ntop(AF_INET6, event.saddr) + "]", 605*387f9dfdSAndroid Build Coastguard Worker "[" + inet_ntop(AF_INET6, event.daddr) + "]", 606*387f9dfdSAndroid Build Coastguard Worker event.sport, 607*387f9dfdSAndroid Build Coastguard Worker event.dport), end="") 608*387f9dfdSAndroid Build Coastguard Worker if args.verbose and not args.netns: 609*387f9dfdSAndroid Build Coastguard Worker print(" %-8d" % event.netns) 610*387f9dfdSAndroid Build Coastguard Worker else: 611*387f9dfdSAndroid Build Coastguard Worker print() 612*387f9dfdSAndroid Build Coastguard Worker 613*387f9dfdSAndroid Build Coastguard Worker 614*387f9dfdSAndroid Build Coastguard Workerpid_filter = "" 615*387f9dfdSAndroid Build Coastguard Workernetns_filter = "" 616*387f9dfdSAndroid Build Coastguard Worker 617*387f9dfdSAndroid Build Coastguard Workerif args.pid: 618*387f9dfdSAndroid Build Coastguard Worker pid_filter = 'if (pid >> 32 != %d) { return 0; }' % args.pid 619*387f9dfdSAndroid Build Coastguard Workerif args.netns: 620*387f9dfdSAndroid Build Coastguard Worker netns_filter = 'if (net_ns_inum != %d) { return 0; }' % args.netns 621*387f9dfdSAndroid Build Coastguard Workerif args.ipv4: 622*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('##FILTER_FAMILY##', 623*387f9dfdSAndroid Build Coastguard Worker 'if (family != AF_INET) { return 0; }') 624*387f9dfdSAndroid Build Coastguard Workerelif args.ipv6: 625*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('##FILTER_FAMILY##', 626*387f9dfdSAndroid Build Coastguard Worker 'if (family != AF_INET6) { return 0; }') 627*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('##FILTER_FAMILY##', '') 628*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('##FILTER_PID##', pid_filter) 629*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('##FILTER_NETNS##', netns_filter) 630*387f9dfdSAndroid Build Coastguard Workerbpf_text = filter_by_containers(args) + bpf_text 631*387f9dfdSAndroid Build Coastguard Worker 632*387f9dfdSAndroid Build Coastguard Workerif args.ebpf: 633*387f9dfdSAndroid Build Coastguard Worker print(bpf_text) 634*387f9dfdSAndroid Build Coastguard Worker exit() 635*387f9dfdSAndroid Build Coastguard Worker 636*387f9dfdSAndroid Build Coastguard Worker# initialize BPF 637*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text) 638*387f9dfdSAndroid Build Coastguard Workerif args.ipv4: 639*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_entry") 640*387f9dfdSAndroid Build Coastguard Worker b.attach_kretprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_return") 641*387f9dfdSAndroid Build Coastguard Workerelif args.ipv6: 642*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_entry") 643*387f9dfdSAndroid Build Coastguard Worker b.attach_kretprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_return") 644*387f9dfdSAndroid Build Coastguard Workerelse: 645*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_entry") 646*387f9dfdSAndroid Build Coastguard Worker b.attach_kretprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_return") 647*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_entry") 648*387f9dfdSAndroid Build Coastguard Worker b.attach_kretprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_return") 649*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="tcp_set_state", fn_name="trace_tcp_set_state_entry") 650*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="tcp_close", fn_name="trace_close_entry") 651*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="inet_csk_accept", fn_name="trace_accept_return") 652*387f9dfdSAndroid Build Coastguard Worker 653*387f9dfdSAndroid Build Coastguard Workerprint("Tracing TCP established connections. Ctrl-C to end.") 654*387f9dfdSAndroid Build Coastguard Worker 655*387f9dfdSAndroid Build Coastguard Worker# header 656*387f9dfdSAndroid Build Coastguard Workerif args.verbose: 657*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 658*387f9dfdSAndroid Build Coastguard Worker print("%-14s" % ("TIME(ns)"), end="") 659*387f9dfdSAndroid Build Coastguard Worker print("%-12s %-6s %-16s %-2s %-16s %-16s %-6s %-7s" % ("TYPE", 660*387f9dfdSAndroid Build Coastguard Worker "PID", "COMM", "IP", "SADDR", "DADDR", "SPORT", "DPORT"), end="") 661*387f9dfdSAndroid Build Coastguard Worker if not args.netns: 662*387f9dfdSAndroid Build Coastguard Worker print("%-8s" % "NETNS", end="") 663*387f9dfdSAndroid Build Coastguard Worker print() 664*387f9dfdSAndroid Build Coastguard Workerelse: 665*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 666*387f9dfdSAndroid Build Coastguard Worker print("%-9s" % ("TIME(s)"), end="") 667*387f9dfdSAndroid Build Coastguard Worker print("%-2s %-6s %-16s %-2s %-16s %-16s %-6s %-6s" % 668*387f9dfdSAndroid Build Coastguard Worker ("T", "PID", "COMM", "IP", "SADDR", "DADDR", "SPORT", "DPORT")) 669*387f9dfdSAndroid Build Coastguard Worker 670*387f9dfdSAndroid Build Coastguard Workerstart_ts = 0 671*387f9dfdSAndroid Build Coastguard Worker 672*387f9dfdSAndroid Build Coastguard Worker 673*387f9dfdSAndroid Build Coastguard Workerb["tcp_ipv4_event"].open_perf_buffer(print_ipv4_event) 674*387f9dfdSAndroid Build Coastguard Workerb["tcp_ipv6_event"].open_perf_buffer(print_ipv6_event) 675*387f9dfdSAndroid Build Coastguard Workerwhile True: 676*387f9dfdSAndroid Build Coastguard Worker try: 677*387f9dfdSAndroid Build Coastguard Worker b.perf_buffer_poll() 678*387f9dfdSAndroid Build Coastguard Worker except KeyboardInterrupt: 679*387f9dfdSAndroid Build Coastguard Worker exit() 680