1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python 2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports 3*387f9dfdSAndroid Build Coastguard Worker# 4*387f9dfdSAndroid Build Coastguard Worker# tcpconnlat Trace TCP active connection latency (connect). 5*387f9dfdSAndroid Build Coastguard Worker# For Linux, uses BCC, eBPF. Embedded C. 6*387f9dfdSAndroid Build Coastguard Worker# 7*387f9dfdSAndroid Build Coastguard Worker# USAGE: tcpconnlat [-h] [-t] [-p PID] [-4 | -6] 8*387f9dfdSAndroid Build Coastguard Worker# 9*387f9dfdSAndroid Build Coastguard Worker# This uses dynamic tracing of kernel functions, and will need to be updated 10*387f9dfdSAndroid Build Coastguard Worker# to match kernel changes. 11*387f9dfdSAndroid Build Coastguard Worker# 12*387f9dfdSAndroid Build Coastguard Worker# Copyright 2016 Netflix, Inc. 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# 19-Feb-2016 Brendan Gregg Created this. 16*387f9dfdSAndroid Build Coastguard Worker# 15-Mar-2021 Suresh Kumar Added LPORT option 17*387f9dfdSAndroid Build Coastguard Worker 18*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function 19*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF 20*387f9dfdSAndroid Build Coastguard Workerfrom socket import inet_ntop, AF_INET, AF_INET6 21*387f9dfdSAndroid Build Coastguard Workerfrom struct import pack 22*387f9dfdSAndroid Build Coastguard Workerimport argparse 23*387f9dfdSAndroid Build Coastguard Worker 24*387f9dfdSAndroid Build Coastguard Worker# arg validation 25*387f9dfdSAndroid Build Coastguard Workerdef positive_float(val): 26*387f9dfdSAndroid Build Coastguard Worker try: 27*387f9dfdSAndroid Build Coastguard Worker ival = float(val) 28*387f9dfdSAndroid Build Coastguard Worker except ValueError: 29*387f9dfdSAndroid Build Coastguard Worker raise argparse.ArgumentTypeError("must be a float") 30*387f9dfdSAndroid Build Coastguard Worker 31*387f9dfdSAndroid Build Coastguard Worker if ival < 0: 32*387f9dfdSAndroid Build Coastguard Worker raise argparse.ArgumentTypeError("must be positive") 33*387f9dfdSAndroid Build Coastguard Worker return ival 34*387f9dfdSAndroid Build Coastguard Worker 35*387f9dfdSAndroid Build Coastguard Worker# arguments 36*387f9dfdSAndroid Build Coastguard Workerexamples = """examples: 37*387f9dfdSAndroid Build Coastguard Worker ./tcpconnlat # trace all TCP connect()s 38*387f9dfdSAndroid Build Coastguard Worker ./tcpconnlat 1 # trace connection latency slower than 1 ms 39*387f9dfdSAndroid Build Coastguard Worker ./tcpconnlat 0.1 # trace connection latency slower than 100 us 40*387f9dfdSAndroid Build Coastguard Worker ./tcpconnlat -t # include timestamps 41*387f9dfdSAndroid Build Coastguard Worker ./tcpconnlat -p 181 # only trace PID 181 42*387f9dfdSAndroid Build Coastguard Worker ./tcpconnlat -L # include LPORT while printing outputs 43*387f9dfdSAndroid Build Coastguard Worker ./tcpconnlat -4 # trace IPv4 family only 44*387f9dfdSAndroid Build Coastguard Worker ./tcpconnlat -6 # trace IPv6 family only 45*387f9dfdSAndroid Build Coastguard Worker""" 46*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser( 47*387f9dfdSAndroid Build Coastguard Worker description="Trace TCP connects and show connection latency", 48*387f9dfdSAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter, 49*387f9dfdSAndroid Build Coastguard Worker epilog=examples) 50*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--timestamp", action="store_true", 51*387f9dfdSAndroid Build Coastguard Worker help="include timestamp on output") 52*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", 53*387f9dfdSAndroid Build Coastguard Worker help="trace this PID only") 54*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-L", "--lport", action="store_true", 55*387f9dfdSAndroid Build Coastguard Worker help="include LPORT on output") 56*387f9dfdSAndroid Build Coastguard Workergroup = parser.add_mutually_exclusive_group() 57*387f9dfdSAndroid Build Coastguard Workergroup.add_argument("-4", "--ipv4", action="store_true", 58*387f9dfdSAndroid Build Coastguard Worker help="trace IPv4 family only") 59*387f9dfdSAndroid Build Coastguard Workergroup.add_argument("-6", "--ipv6", action="store_true", 60*387f9dfdSAndroid Build Coastguard Worker help="trace IPv6 family only") 61*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("duration_ms", nargs="?", default=0, 62*387f9dfdSAndroid Build Coastguard Worker type=positive_float, 63*387f9dfdSAndroid Build Coastguard Worker help="minimum duration to trace (ms)") 64*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-v", "--verbose", action="store_true", 65*387f9dfdSAndroid Build Coastguard Worker help="print the BPF program for debugging purposes") 66*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true", 67*387f9dfdSAndroid Build Coastguard Worker help=argparse.SUPPRESS) 68*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args() 69*387f9dfdSAndroid Build Coastguard Worker 70*387f9dfdSAndroid Build Coastguard Workerif args.duration_ms: 71*387f9dfdSAndroid Build Coastguard Worker # support fractions but round to nearest microsecond 72*387f9dfdSAndroid Build Coastguard Worker duration_us = int(args.duration_ms * 1000) 73*387f9dfdSAndroid Build Coastguard Workerelse: 74*387f9dfdSAndroid Build Coastguard Worker duration_us = 0 # default is show all 75*387f9dfdSAndroid Build Coastguard Worker 76*387f9dfdSAndroid Build Coastguard Workerdebug = 0 77*387f9dfdSAndroid Build Coastguard Worker 78*387f9dfdSAndroid Build Coastguard Worker# define BPF program 79*387f9dfdSAndroid Build Coastguard Workerbpf_text = """ 80*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h> 81*387f9dfdSAndroid Build Coastguard Worker#include <net/sock.h> 82*387f9dfdSAndroid Build Coastguard Worker#include <net/tcp_states.h> 83*387f9dfdSAndroid Build Coastguard Worker#include <bcc/proto.h> 84*387f9dfdSAndroid Build Coastguard Worker 85*387f9dfdSAndroid Build Coastguard Workerstruct info_t { 86*387f9dfdSAndroid Build Coastguard Worker u64 ts; 87*387f9dfdSAndroid Build Coastguard Worker u32 pid; 88*387f9dfdSAndroid Build Coastguard Worker char task[TASK_COMM_LEN]; 89*387f9dfdSAndroid Build Coastguard Worker}; 90*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(start, struct sock *, struct info_t); 91*387f9dfdSAndroid Build Coastguard Worker 92*387f9dfdSAndroid Build Coastguard Worker// separate data structs for ipv4 and ipv6 93*387f9dfdSAndroid Build Coastguard Workerstruct ipv4_data_t { 94*387f9dfdSAndroid Build Coastguard Worker u64 ts_us; 95*387f9dfdSAndroid Build Coastguard Worker u32 pid; 96*387f9dfdSAndroid Build Coastguard Worker u32 saddr; 97*387f9dfdSAndroid Build Coastguard Worker u32 daddr; 98*387f9dfdSAndroid Build Coastguard Worker u64 ip; 99*387f9dfdSAndroid Build Coastguard Worker u16 lport; 100*387f9dfdSAndroid Build Coastguard Worker u16 dport; 101*387f9dfdSAndroid Build Coastguard Worker u64 delta_us; 102*387f9dfdSAndroid Build Coastguard Worker char task[TASK_COMM_LEN]; 103*387f9dfdSAndroid Build Coastguard Worker}; 104*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(ipv4_events); 105*387f9dfdSAndroid Build Coastguard Worker 106*387f9dfdSAndroid Build Coastguard Workerstruct ipv6_data_t { 107*387f9dfdSAndroid Build Coastguard Worker u64 ts_us; 108*387f9dfdSAndroid Build Coastguard Worker u32 pid; 109*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 saddr; 110*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 daddr; 111*387f9dfdSAndroid Build Coastguard Worker u64 ip; 112*387f9dfdSAndroid Build Coastguard Worker u16 lport; 113*387f9dfdSAndroid Build Coastguard Worker u16 dport; 114*387f9dfdSAndroid Build Coastguard Worker u64 delta_us; 115*387f9dfdSAndroid Build Coastguard Worker char task[TASK_COMM_LEN]; 116*387f9dfdSAndroid Build Coastguard Worker}; 117*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(ipv6_events); 118*387f9dfdSAndroid Build Coastguard Worker 119*387f9dfdSAndroid Build Coastguard Workerint trace_connect(struct pt_regs *ctx, struct sock *sk) 120*387f9dfdSAndroid Build Coastguard Worker{ 121*387f9dfdSAndroid Build Coastguard Worker u32 pid = bpf_get_current_pid_tgid() >> 32; 122*387f9dfdSAndroid Build Coastguard Worker FILTER 123*387f9dfdSAndroid Build Coastguard Worker struct info_t info = {.pid = pid}; 124*387f9dfdSAndroid Build Coastguard Worker info.ts = bpf_ktime_get_ns(); 125*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&info.task, sizeof(info.task)); 126*387f9dfdSAndroid Build Coastguard Worker start.update(&sk, &info); 127*387f9dfdSAndroid Build Coastguard Worker return 0; 128*387f9dfdSAndroid Build Coastguard Worker}; 129*387f9dfdSAndroid Build Coastguard Worker 130*387f9dfdSAndroid Build Coastguard Worker// See tcp_v4_do_rcv() and tcp_v6_do_rcv(). So TCP_ESTBALISHED and TCP_LISTEN 131*387f9dfdSAndroid Build Coastguard Worker// are fast path and processed elsewhere, and leftovers are processed by 132*387f9dfdSAndroid Build Coastguard Worker// tcp_rcv_state_process(). We can trace this for handshake completion. 133*387f9dfdSAndroid Build Coastguard Worker// This should all be switched to static tracepoints when available. 134*387f9dfdSAndroid Build Coastguard Workerint trace_tcp_rcv_state_process(struct pt_regs *ctx, struct sock *skp) 135*387f9dfdSAndroid Build Coastguard Worker{ 136*387f9dfdSAndroid Build Coastguard Worker // will be in TCP_SYN_SENT for handshake 137*387f9dfdSAndroid Build Coastguard Worker if (skp->__sk_common.skc_state != TCP_SYN_SENT) 138*387f9dfdSAndroid Build Coastguard Worker return 0; 139*387f9dfdSAndroid Build Coastguard Worker 140*387f9dfdSAndroid Build Coastguard Worker // check start and calculate delta 141*387f9dfdSAndroid Build Coastguard Worker struct info_t *infop = start.lookup(&skp); 142*387f9dfdSAndroid Build Coastguard Worker if (infop == 0) { 143*387f9dfdSAndroid Build Coastguard Worker return 0; // missed entry or filtered 144*387f9dfdSAndroid Build Coastguard Worker } 145*387f9dfdSAndroid Build Coastguard Worker 146*387f9dfdSAndroid Build Coastguard Worker u64 ts = infop->ts; 147*387f9dfdSAndroid Build Coastguard Worker u64 now = bpf_ktime_get_ns(); 148*387f9dfdSAndroid Build Coastguard Worker 149*387f9dfdSAndroid Build Coastguard Worker u64 delta_us = (now - ts) / 1000ul; 150*387f9dfdSAndroid Build Coastguard Worker 151*387f9dfdSAndroid Build Coastguard Worker#ifdef MIN_LATENCY 152*387f9dfdSAndroid Build Coastguard Worker if ( delta_us < DURATION_US ) { 153*387f9dfdSAndroid Build Coastguard Worker return 0; // connect latency is below latency filter minimum 154*387f9dfdSAndroid Build Coastguard Worker } 155*387f9dfdSAndroid Build Coastguard Worker#endif 156*387f9dfdSAndroid Build Coastguard Worker 157*387f9dfdSAndroid Build Coastguard Worker // pull in details 158*387f9dfdSAndroid Build Coastguard Worker u16 family = 0, lport = 0, dport = 0; 159*387f9dfdSAndroid Build Coastguard Worker family = skp->__sk_common.skc_family; 160*387f9dfdSAndroid Build Coastguard Worker lport = skp->__sk_common.skc_num; 161*387f9dfdSAndroid Build Coastguard Worker dport = skp->__sk_common.skc_dport; 162*387f9dfdSAndroid Build Coastguard Worker 163*387f9dfdSAndroid Build Coastguard Worker // emit to appropriate data path 164*387f9dfdSAndroid Build Coastguard Worker if (family == AF_INET) { 165*387f9dfdSAndroid Build Coastguard Worker struct ipv4_data_t data4 = {.pid = infop->pid, .ip = 4}; 166*387f9dfdSAndroid Build Coastguard Worker data4.ts_us = now / 1000; 167*387f9dfdSAndroid Build Coastguard Worker data4.saddr = skp->__sk_common.skc_rcv_saddr; 168*387f9dfdSAndroid Build Coastguard Worker data4.daddr = skp->__sk_common.skc_daddr; 169*387f9dfdSAndroid Build Coastguard Worker data4.lport = lport; 170*387f9dfdSAndroid Build Coastguard Worker data4.dport = ntohs(dport); 171*387f9dfdSAndroid Build Coastguard Worker data4.delta_us = delta_us; 172*387f9dfdSAndroid Build Coastguard Worker __builtin_memcpy(&data4.task, infop->task, sizeof(data4.task)); 173*387f9dfdSAndroid Build Coastguard Worker ipv4_events.perf_submit(ctx, &data4, sizeof(data4)); 174*387f9dfdSAndroid Build Coastguard Worker 175*387f9dfdSAndroid Build Coastguard Worker } else /* AF_INET6 */ { 176*387f9dfdSAndroid Build Coastguard Worker struct ipv6_data_t data6 = {.pid = infop->pid, .ip = 6}; 177*387f9dfdSAndroid Build Coastguard Worker data6.ts_us = now / 1000; 178*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&data6.saddr, sizeof(data6.saddr), 179*387f9dfdSAndroid Build Coastguard Worker skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); 180*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&data6.daddr, sizeof(data6.daddr), 181*387f9dfdSAndroid Build Coastguard Worker skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32); 182*387f9dfdSAndroid Build Coastguard Worker data6.lport = lport; 183*387f9dfdSAndroid Build Coastguard Worker data6.dport = ntohs(dport); 184*387f9dfdSAndroid Build Coastguard Worker data6.delta_us = delta_us; 185*387f9dfdSAndroid Build Coastguard Worker __builtin_memcpy(&data6.task, infop->task, sizeof(data6.task)); 186*387f9dfdSAndroid Build Coastguard Worker ipv6_events.perf_submit(ctx, &data6, sizeof(data6)); 187*387f9dfdSAndroid Build Coastguard Worker } 188*387f9dfdSAndroid Build Coastguard Worker 189*387f9dfdSAndroid Build Coastguard Worker start.delete(&skp); 190*387f9dfdSAndroid Build Coastguard Worker 191*387f9dfdSAndroid Build Coastguard Worker return 0; 192*387f9dfdSAndroid Build Coastguard Worker} 193*387f9dfdSAndroid Build Coastguard Worker""" 194*387f9dfdSAndroid Build Coastguard Worker 195*387f9dfdSAndroid Build Coastguard Workerif duration_us > 0: 196*387f9dfdSAndroid Build Coastguard Worker bpf_text = "#define MIN_LATENCY\n" + bpf_text 197*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('DURATION_US', str(duration_us)) 198*387f9dfdSAndroid Build Coastguard Worker 199*387f9dfdSAndroid Build Coastguard Worker# code substitutions 200*387f9dfdSAndroid Build Coastguard Workerif args.pid: 201*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER', 202*387f9dfdSAndroid Build Coastguard Worker 'if (pid != %s) { return 0; }' % args.pid) 203*387f9dfdSAndroid Build Coastguard Workerelse: 204*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER', '') 205*387f9dfdSAndroid Build Coastguard Workerif debug or args.verbose or args.ebpf: 206*387f9dfdSAndroid Build Coastguard Worker print(bpf_text) 207*387f9dfdSAndroid Build Coastguard Worker if args.ebpf: 208*387f9dfdSAndroid Build Coastguard Worker exit() 209*387f9dfdSAndroid Build Coastguard Worker 210*387f9dfdSAndroid Build Coastguard Worker# initialize BPF 211*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text) 212*387f9dfdSAndroid Build Coastguard Workerif args.ipv4: 213*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect") 214*387f9dfdSAndroid Build Coastguard Workerelif args.ipv6: 215*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect") 216*387f9dfdSAndroid Build Coastguard Workerelse: 217*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect") 218*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect") 219*387f9dfdSAndroid Build Coastguard Worker 220*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="tcp_rcv_state_process", 221*387f9dfdSAndroid Build Coastguard Worker fn_name="trace_tcp_rcv_state_process") 222*387f9dfdSAndroid Build Coastguard Worker 223*387f9dfdSAndroid Build Coastguard Worker# process event 224*387f9dfdSAndroid Build Coastguard Workerstart_ts = 0 225*387f9dfdSAndroid Build Coastguard Worker 226*387f9dfdSAndroid Build Coastguard Workerdef print_ipv4_event(cpu, data, size): 227*387f9dfdSAndroid Build Coastguard Worker event = b["ipv4_events"].event(data) 228*387f9dfdSAndroid Build Coastguard Worker global start_ts 229*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 230*387f9dfdSAndroid Build Coastguard Worker if start_ts == 0: 231*387f9dfdSAndroid Build Coastguard Worker start_ts = event.ts_us 232*387f9dfdSAndroid Build Coastguard Worker print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="") 233*387f9dfdSAndroid Build Coastguard Worker if args.lport: 234*387f9dfdSAndroid Build Coastguard Worker print("%-7d %-12.12s %-2d %-16s %-6d %-16s %-5d %.2f" % (event.pid, 235*387f9dfdSAndroid Build Coastguard Worker event.task.decode('utf-8', 'replace'), event.ip, 236*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack("I", event.saddr)), event.lport, 237*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack("I", event.daddr)), event.dport, 238*387f9dfdSAndroid Build Coastguard Worker float(event.delta_us) / 1000)) 239*387f9dfdSAndroid Build Coastguard Worker else: 240*387f9dfdSAndroid Build Coastguard Worker print("%-7d %-12.12s %-2d %-16s %-16s %-5d %.2f" % (event.pid, 241*387f9dfdSAndroid Build Coastguard Worker event.task.decode('utf-8', 'replace'), event.ip, 242*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack("I", event.saddr)), 243*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack("I", event.daddr)), event.dport, 244*387f9dfdSAndroid Build Coastguard Worker float(event.delta_us) / 1000)) 245*387f9dfdSAndroid Build Coastguard Worker 246*387f9dfdSAndroid Build Coastguard Workerdef print_ipv6_event(cpu, data, size): 247*387f9dfdSAndroid Build Coastguard Worker event = b["ipv6_events"].event(data) 248*387f9dfdSAndroid Build Coastguard Worker global start_ts 249*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 250*387f9dfdSAndroid Build Coastguard Worker if start_ts == 0: 251*387f9dfdSAndroid Build Coastguard Worker start_ts = event.ts_us 252*387f9dfdSAndroid Build Coastguard Worker print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="") 253*387f9dfdSAndroid Build Coastguard Worker if args.lport: 254*387f9dfdSAndroid Build Coastguard Worker print("%-7d %-12.12s %-2d %-16s %-6d %-16s %-5d %.2f" % (event.pid, 255*387f9dfdSAndroid Build Coastguard Worker event.task.decode('utf-8', 'replace'), event.ip, 256*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET6, event.saddr), event.lport, 257*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET6, event.daddr), 258*387f9dfdSAndroid Build Coastguard Worker event.dport, float(event.delta_us) / 1000)) 259*387f9dfdSAndroid Build Coastguard Worker else: 260*387f9dfdSAndroid Build Coastguard Worker print("%-7d %-12.12s %-2d %-16s %-16s %-5d %.2f" % (event.pid, 261*387f9dfdSAndroid Build Coastguard Worker event.task.decode('utf-8', 'replace'), event.ip, 262*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET6, event.saddr), inet_ntop(AF_INET6, event.daddr), 263*387f9dfdSAndroid Build Coastguard Worker event.dport, float(event.delta_us) / 1000)) 264*387f9dfdSAndroid Build Coastguard Worker 265*387f9dfdSAndroid Build Coastguard Worker# header 266*387f9dfdSAndroid Build Coastguard Workerif args.timestamp: 267*387f9dfdSAndroid Build Coastguard Worker print("%-9s" % ("TIME(s)"), end="") 268*387f9dfdSAndroid Build Coastguard Workerif args.lport: 269*387f9dfdSAndroid Build Coastguard Worker print("%-7s %-12s %-2s %-16s %-6s %-16s %-5s %s" % ("PID", "COMM", 270*387f9dfdSAndroid Build Coastguard Worker "IP", "SADDR", "LPORT", "DADDR", "DPORT", "LAT(ms)")) 271*387f9dfdSAndroid Build Coastguard Workerelse: 272*387f9dfdSAndroid Build Coastguard Worker print("%-7s %-12s %-2s %-16s %-16s %-5s %s" % ("PID", "COMM", "IP", 273*387f9dfdSAndroid Build Coastguard Worker "SADDR", "DADDR", "DPORT", "LAT(ms)")) 274*387f9dfdSAndroid Build Coastguard Worker 275*387f9dfdSAndroid Build Coastguard Worker# read events 276*387f9dfdSAndroid Build Coastguard Workerif args.ipv4: 277*387f9dfdSAndroid Build Coastguard Worker b["ipv4_events"].open_perf_buffer(print_ipv4_event) 278*387f9dfdSAndroid Build Coastguard Workerelif args.ipv6: 279*387f9dfdSAndroid Build Coastguard Worker b["ipv6_events"].open_perf_buffer(print_ipv6_event) 280*387f9dfdSAndroid Build Coastguard Workerelse: 281*387f9dfdSAndroid Build Coastguard Worker b["ipv4_events"].open_perf_buffer(print_ipv4_event) 282*387f9dfdSAndroid Build Coastguard Worker b["ipv6_events"].open_perf_buffer(print_ipv6_event) 283*387f9dfdSAndroid Build Coastguard Worker 284*387f9dfdSAndroid Build Coastguard Workerwhile 1: 285*387f9dfdSAndroid Build Coastguard Worker try: 286*387f9dfdSAndroid Build Coastguard Worker b.perf_buffer_poll() 287*387f9dfdSAndroid Build Coastguard Worker except KeyboardInterrupt: 288*387f9dfdSAndroid Build Coastguard Worker exit() 289