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# tcpconnect Trace TCP connect()s. 5*387f9dfdSAndroid Build Coastguard Worker# For Linux, uses BCC, eBPF. Embedded C. 6*387f9dfdSAndroid Build Coastguard Worker# 7*387f9dfdSAndroid Build Coastguard Worker# USAGE: tcpconnect [-h] [-c] [-t] [-p PID] [-P PORT [PORT ...]] [-4 | -6] 8*387f9dfdSAndroid Build Coastguard Worker# 9*387f9dfdSAndroid Build Coastguard Worker# All connection attempts are traced, even if they ultimately fail. 10*387f9dfdSAndroid Build Coastguard Worker# 11*387f9dfdSAndroid Build Coastguard Worker# This uses dynamic tracing of kernel functions, and will need to be updated 12*387f9dfdSAndroid Build Coastguard Worker# to match kernel changes. 13*387f9dfdSAndroid Build Coastguard Worker# 14*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) 2015 Brendan Gregg. 15*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License") 16*387f9dfdSAndroid Build Coastguard Worker# 17*387f9dfdSAndroid Build Coastguard Worker# 25-Sep-2015 Brendan Gregg Created this. 18*387f9dfdSAndroid Build Coastguard Worker# 14-Feb-2016 " " Switch to bpf_perf_output. 19*387f9dfdSAndroid Build Coastguard Worker# 09-Jan-2019 Takuma Kume Support filtering by UID 20*387f9dfdSAndroid Build Coastguard Worker# 30-Jul-2019 Xiaozhou Liu Count connects. 21*387f9dfdSAndroid Build Coastguard Worker# 07-Oct-2020 Nabil Schear Correlate connects with DNS responses 22*387f9dfdSAndroid Build Coastguard Worker# 08-Mar-2021 Suresh Kumar Added LPORT option 23*387f9dfdSAndroid Build Coastguard Worker 24*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function 25*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF 26*387f9dfdSAndroid Build Coastguard Workerfrom bcc.containers import filter_by_containers 27*387f9dfdSAndroid Build Coastguard Workerfrom bcc.utils import printb 28*387f9dfdSAndroid Build Coastguard Workerimport argparse 29*387f9dfdSAndroid Build Coastguard Workerfrom socket import inet_ntop, ntohs, AF_INET, AF_INET6 30*387f9dfdSAndroid Build Coastguard Workerfrom struct import pack 31*387f9dfdSAndroid Build Coastguard Workerfrom time import sleep 32*387f9dfdSAndroid Build Coastguard Workerfrom datetime import datetime 33*387f9dfdSAndroid Build Coastguard Worker 34*387f9dfdSAndroid Build Coastguard Worker# arguments 35*387f9dfdSAndroid Build Coastguard Workerexamples = """examples: 36*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect # trace all TCP connect()s 37*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -t # include timestamps 38*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -d # include DNS queries associated with connects 39*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -p 181 # only trace PID 181 40*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -P 80 # only trace port 80 41*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -P 80,81 # only trace port 80 and 81 42*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -4 # only trace IPv4 family 43*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -6 # only trace IPv6 family 44*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -U # include UID 45*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -u 1000 # only trace UID 1000 46*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -c # count connects per src ip and dest ip/port 47*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect -L # include LPORT while printing outputs 48*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect --cgroupmap mappath # only trace cgroups in this BPF map 49*387f9dfdSAndroid Build Coastguard Worker ./tcpconnect --mntnsmap mappath # only trace mount namespaces in the map 50*387f9dfdSAndroid Build Coastguard Worker""" 51*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser( 52*387f9dfdSAndroid Build Coastguard Worker description="Trace TCP connects", 53*387f9dfdSAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter, 54*387f9dfdSAndroid Build Coastguard Worker epilog=examples) 55*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--timestamp", action="store_true", 56*387f9dfdSAndroid Build Coastguard Worker help="include timestamp on output") 57*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", 58*387f9dfdSAndroid Build Coastguard Worker help="trace this PID only") 59*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-P", "--port", 60*387f9dfdSAndroid Build Coastguard Worker help="comma-separated list of destination ports to trace.") 61*387f9dfdSAndroid Build Coastguard Workergroup = parser.add_mutually_exclusive_group() 62*387f9dfdSAndroid Build Coastguard Workergroup.add_argument("-4", "--ipv4", action="store_true", 63*387f9dfdSAndroid Build Coastguard Worker help="trace IPv4 family only") 64*387f9dfdSAndroid Build Coastguard Workergroup.add_argument("-6", "--ipv6", action="store_true", 65*387f9dfdSAndroid Build Coastguard Worker help="trace IPv6 family only") 66*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-L", "--lport", action="store_true", 67*387f9dfdSAndroid Build Coastguard Worker help="include LPORT on output") 68*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-U", "--print-uid", action="store_true", 69*387f9dfdSAndroid Build Coastguard Worker help="include UID on output") 70*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-u", "--uid", 71*387f9dfdSAndroid Build Coastguard Worker help="trace this UID only") 72*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-c", "--count", action="store_true", 73*387f9dfdSAndroid Build Coastguard Worker help="count connects per src ip and dest ip/port") 74*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--cgroupmap", 75*387f9dfdSAndroid Build Coastguard Worker help="trace cgroups in this BPF map only") 76*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--mntnsmap", 77*387f9dfdSAndroid Build Coastguard Worker help="trace mount namespaces in this BPF map only") 78*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-d", "--dns", action="store_true", 79*387f9dfdSAndroid Build Coastguard Worker help="include likely DNS query associated with each connect") 80*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true", 81*387f9dfdSAndroid Build Coastguard Worker help=argparse.SUPPRESS) 82*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args() 83*387f9dfdSAndroid Build Coastguard Workerdebug = 0 84*387f9dfdSAndroid Build Coastguard Worker 85*387f9dfdSAndroid Build Coastguard Worker# define BPF program 86*387f9dfdSAndroid Build Coastguard Workerbpf_text = """ 87*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h> 88*387f9dfdSAndroid Build Coastguard Worker#include <net/sock.h> 89*387f9dfdSAndroid Build Coastguard Worker#include <bcc/proto.h> 90*387f9dfdSAndroid Build Coastguard Worker 91*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(currsock, u32, struct sock *); 92*387f9dfdSAndroid Build Coastguard Worker 93*387f9dfdSAndroid Build Coastguard Worker// separate data structs for ipv4 and ipv6 94*387f9dfdSAndroid Build Coastguard Workerstruct ipv4_data_t { 95*387f9dfdSAndroid Build Coastguard Worker u64 ts_us; 96*387f9dfdSAndroid Build Coastguard Worker u32 pid; 97*387f9dfdSAndroid Build Coastguard Worker u32 uid; 98*387f9dfdSAndroid Build Coastguard Worker u32 saddr; 99*387f9dfdSAndroid Build Coastguard Worker u32 daddr; 100*387f9dfdSAndroid Build Coastguard Worker u64 ip; 101*387f9dfdSAndroid Build Coastguard Worker u16 lport; 102*387f9dfdSAndroid Build Coastguard Worker u16 dport; 103*387f9dfdSAndroid Build Coastguard Worker char task[TASK_COMM_LEN]; 104*387f9dfdSAndroid Build Coastguard Worker}; 105*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(ipv4_events); 106*387f9dfdSAndroid Build Coastguard Worker 107*387f9dfdSAndroid Build Coastguard Workerstruct ipv6_data_t { 108*387f9dfdSAndroid Build Coastguard Worker u64 ts_us; 109*387f9dfdSAndroid Build Coastguard Worker u32 pid; 110*387f9dfdSAndroid Build Coastguard Worker u32 uid; 111*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 saddr; 112*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 daddr; 113*387f9dfdSAndroid Build Coastguard Worker u64 ip; 114*387f9dfdSAndroid Build Coastguard Worker u16 lport; 115*387f9dfdSAndroid Build Coastguard Worker u16 dport; 116*387f9dfdSAndroid Build Coastguard Worker char task[TASK_COMM_LEN]; 117*387f9dfdSAndroid Build Coastguard Worker}; 118*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(ipv6_events); 119*387f9dfdSAndroid Build Coastguard Worker 120*387f9dfdSAndroid Build Coastguard Worker// separate flow keys per address family 121*387f9dfdSAndroid Build Coastguard Workerstruct ipv4_flow_key_t { 122*387f9dfdSAndroid Build Coastguard Worker u32 saddr; 123*387f9dfdSAndroid Build Coastguard Worker u32 daddr; 124*387f9dfdSAndroid Build Coastguard Worker u16 dport; 125*387f9dfdSAndroid Build Coastguard Worker}; 126*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(ipv4_count, struct ipv4_flow_key_t); 127*387f9dfdSAndroid Build Coastguard Worker 128*387f9dfdSAndroid Build Coastguard Workerstruct ipv6_flow_key_t { 129*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 saddr; 130*387f9dfdSAndroid Build Coastguard Worker unsigned __int128 daddr; 131*387f9dfdSAndroid Build Coastguard Worker u16 dport; 132*387f9dfdSAndroid Build Coastguard Worker}; 133*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(ipv6_count, struct ipv6_flow_key_t); 134*387f9dfdSAndroid Build Coastguard Worker 135*387f9dfdSAndroid Build Coastguard Workerint trace_connect_entry(struct pt_regs *ctx, struct sock *sk) 136*387f9dfdSAndroid Build Coastguard Worker{ 137*387f9dfdSAndroid Build Coastguard Worker if (container_should_be_filtered()) { 138*387f9dfdSAndroid Build Coastguard Worker return 0; 139*387f9dfdSAndroid Build Coastguard Worker } 140*387f9dfdSAndroid Build Coastguard Worker 141*387f9dfdSAndroid Build Coastguard Worker u64 pid_tgid = bpf_get_current_pid_tgid(); 142*387f9dfdSAndroid Build Coastguard Worker u32 pid = pid_tgid >> 32; 143*387f9dfdSAndroid Build Coastguard Worker u32 tid = pid_tgid; 144*387f9dfdSAndroid Build Coastguard Worker FILTER_PID 145*387f9dfdSAndroid Build Coastguard Worker 146*387f9dfdSAndroid Build Coastguard Worker u32 uid = bpf_get_current_uid_gid(); 147*387f9dfdSAndroid Build Coastguard Worker FILTER_UID 148*387f9dfdSAndroid Build Coastguard Worker 149*387f9dfdSAndroid Build Coastguard Worker // stash the sock ptr for lookup on return 150*387f9dfdSAndroid Build Coastguard Worker currsock.update(&tid, &sk); 151*387f9dfdSAndroid Build Coastguard Worker 152*387f9dfdSAndroid Build Coastguard Worker return 0; 153*387f9dfdSAndroid Build Coastguard Worker}; 154*387f9dfdSAndroid Build Coastguard Worker 155*387f9dfdSAndroid Build Coastguard Workerstatic int trace_connect_return(struct pt_regs *ctx, short ipver) 156*387f9dfdSAndroid Build Coastguard Worker{ 157*387f9dfdSAndroid Build Coastguard Worker int ret = PT_REGS_RC(ctx); 158*387f9dfdSAndroid Build Coastguard Worker u64 pid_tgid = bpf_get_current_pid_tgid(); 159*387f9dfdSAndroid Build Coastguard Worker u32 pid = pid_tgid >> 32; 160*387f9dfdSAndroid Build Coastguard Worker u32 tid = pid_tgid; 161*387f9dfdSAndroid Build Coastguard Worker 162*387f9dfdSAndroid Build Coastguard Worker struct sock **skpp; 163*387f9dfdSAndroid Build Coastguard Worker skpp = currsock.lookup(&tid); 164*387f9dfdSAndroid Build Coastguard Worker if (skpp == 0) { 165*387f9dfdSAndroid Build Coastguard Worker return 0; // missed entry 166*387f9dfdSAndroid Build Coastguard Worker } 167*387f9dfdSAndroid Build Coastguard Worker 168*387f9dfdSAndroid Build Coastguard Worker if (ret != 0) { 169*387f9dfdSAndroid Build Coastguard Worker // failed to send SYNC packet, may not have populated 170*387f9dfdSAndroid Build Coastguard Worker // socket __sk_common.{skc_rcv_saddr, ...} 171*387f9dfdSAndroid Build Coastguard Worker currsock.delete(&tid); 172*387f9dfdSAndroid Build Coastguard Worker return 0; 173*387f9dfdSAndroid Build Coastguard Worker } 174*387f9dfdSAndroid Build Coastguard Worker 175*387f9dfdSAndroid Build Coastguard Worker // pull in details 176*387f9dfdSAndroid Build Coastguard Worker struct sock *skp = *skpp; 177*387f9dfdSAndroid Build Coastguard Worker u16 lport = skp->__sk_common.skc_num; 178*387f9dfdSAndroid Build Coastguard Worker u16 dport = skp->__sk_common.skc_dport; 179*387f9dfdSAndroid Build Coastguard Worker 180*387f9dfdSAndroid Build Coastguard Worker FILTER_PORT 181*387f9dfdSAndroid Build Coastguard Worker 182*387f9dfdSAndroid Build Coastguard Worker FILTER_FAMILY 183*387f9dfdSAndroid Build Coastguard Worker 184*387f9dfdSAndroid Build Coastguard Worker if (ipver == 4) { 185*387f9dfdSAndroid Build Coastguard Worker IPV4_CODE 186*387f9dfdSAndroid Build Coastguard Worker } else /* 6 */ { 187*387f9dfdSAndroid Build Coastguard Worker IPV6_CODE 188*387f9dfdSAndroid Build Coastguard Worker } 189*387f9dfdSAndroid Build Coastguard Worker 190*387f9dfdSAndroid Build Coastguard Worker currsock.delete(&tid); 191*387f9dfdSAndroid Build Coastguard Worker 192*387f9dfdSAndroid Build Coastguard Worker return 0; 193*387f9dfdSAndroid Build Coastguard Worker} 194*387f9dfdSAndroid Build Coastguard Worker 195*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v4_return(struct pt_regs *ctx) 196*387f9dfdSAndroid Build Coastguard Worker{ 197*387f9dfdSAndroid Build Coastguard Worker return trace_connect_return(ctx, 4); 198*387f9dfdSAndroid Build Coastguard Worker} 199*387f9dfdSAndroid Build Coastguard Worker 200*387f9dfdSAndroid Build Coastguard Workerint trace_connect_v6_return(struct pt_regs *ctx) 201*387f9dfdSAndroid Build Coastguard Worker{ 202*387f9dfdSAndroid Build Coastguard Worker return trace_connect_return(ctx, 6); 203*387f9dfdSAndroid Build Coastguard Worker} 204*387f9dfdSAndroid Build Coastguard Worker""" 205*387f9dfdSAndroid Build Coastguard Worker 206*387f9dfdSAndroid Build Coastguard Workerstruct_init = {'ipv4': 207*387f9dfdSAndroid Build Coastguard Worker {'count': 208*387f9dfdSAndroid Build Coastguard Worker """ 209*387f9dfdSAndroid Build Coastguard Worker struct ipv4_flow_key_t flow_key = {}; 210*387f9dfdSAndroid Build Coastguard Worker flow_key.saddr = skp->__sk_common.skc_rcv_saddr; 211*387f9dfdSAndroid Build Coastguard Worker flow_key.daddr = skp->__sk_common.skc_daddr; 212*387f9dfdSAndroid Build Coastguard Worker flow_key.dport = ntohs(dport); 213*387f9dfdSAndroid Build Coastguard Worker ipv4_count.increment(flow_key);""", 214*387f9dfdSAndroid Build Coastguard Worker 'trace': 215*387f9dfdSAndroid Build Coastguard Worker """ 216*387f9dfdSAndroid Build Coastguard Worker struct ipv4_data_t data4 = {.pid = pid, .ip = ipver}; 217*387f9dfdSAndroid Build Coastguard Worker data4.uid = bpf_get_current_uid_gid(); 218*387f9dfdSAndroid Build Coastguard Worker data4.ts_us = bpf_ktime_get_ns() / 1000; 219*387f9dfdSAndroid Build Coastguard Worker data4.saddr = skp->__sk_common.skc_rcv_saddr; 220*387f9dfdSAndroid Build Coastguard Worker data4.daddr = skp->__sk_common.skc_daddr; 221*387f9dfdSAndroid Build Coastguard Worker data4.lport = lport; 222*387f9dfdSAndroid Build Coastguard Worker data4.dport = ntohs(dport); 223*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&data4.task, sizeof(data4.task)); 224*387f9dfdSAndroid Build Coastguard Worker ipv4_events.perf_submit(ctx, &data4, sizeof(data4));""" 225*387f9dfdSAndroid Build Coastguard Worker }, 226*387f9dfdSAndroid Build Coastguard Worker 'ipv6': 227*387f9dfdSAndroid Build Coastguard Worker {'count': 228*387f9dfdSAndroid Build Coastguard Worker """ 229*387f9dfdSAndroid Build Coastguard Worker struct ipv6_flow_key_t flow_key = {}; 230*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&flow_key.saddr, sizeof(flow_key.saddr), 231*387f9dfdSAndroid Build Coastguard Worker skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); 232*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&flow_key.daddr, sizeof(flow_key.daddr), 233*387f9dfdSAndroid Build Coastguard Worker skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32); 234*387f9dfdSAndroid Build Coastguard Worker flow_key.dport = ntohs(dport); 235*387f9dfdSAndroid Build Coastguard Worker ipv6_count.increment(flow_key);""", 236*387f9dfdSAndroid Build Coastguard Worker 'trace': 237*387f9dfdSAndroid Build Coastguard Worker """ 238*387f9dfdSAndroid Build Coastguard Worker struct ipv6_data_t data6 = {.pid = pid, .ip = ipver}; 239*387f9dfdSAndroid Build Coastguard Worker data6.uid = bpf_get_current_uid_gid(); 240*387f9dfdSAndroid Build Coastguard Worker data6.ts_us = bpf_ktime_get_ns() / 1000; 241*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&data6.saddr, sizeof(data6.saddr), 242*387f9dfdSAndroid Build Coastguard Worker skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); 243*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_kernel(&data6.daddr, sizeof(data6.daddr), 244*387f9dfdSAndroid Build Coastguard Worker skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32); 245*387f9dfdSAndroid Build Coastguard Worker data6.lport = lport; 246*387f9dfdSAndroid Build Coastguard Worker data6.dport = ntohs(dport); 247*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&data6.task, sizeof(data6.task)); 248*387f9dfdSAndroid Build Coastguard Worker ipv6_events.perf_submit(ctx, &data6, sizeof(data6));""" 249*387f9dfdSAndroid Build Coastguard Worker } 250*387f9dfdSAndroid Build Coastguard Worker } 251*387f9dfdSAndroid Build Coastguard Worker 252*387f9dfdSAndroid Build Coastguard Worker# This defines an additional BPF program that instruments udp_recvmsg system 253*387f9dfdSAndroid Build Coastguard Worker# call to locate DNS response packets on UDP port 53. When these packets are 254*387f9dfdSAndroid Build Coastguard Worker# located, the data is copied to user-space where python will parse them with 255*387f9dfdSAndroid Build Coastguard Worker# dnslib. 256*387f9dfdSAndroid Build Coastguard Worker# 257*387f9dfdSAndroid Build Coastguard Worker# uses a percpu array of length 1 to store the dns_data_t off the stack to 258*387f9dfdSAndroid Build Coastguard Worker# allow for a maximum DNS packet length of 512 bytes. 259*387f9dfdSAndroid Build Coastguard Workerdns_bpf_text = """ 260*387f9dfdSAndroid Build Coastguard Worker#include <net/inet_sock.h> 261*387f9dfdSAndroid Build Coastguard Worker 262*387f9dfdSAndroid Build Coastguard Worker#define MAX_PKT 512 263*387f9dfdSAndroid Build Coastguard Workerstruct dns_data_t { 264*387f9dfdSAndroid Build Coastguard Worker u8 pkt[MAX_PKT]; 265*387f9dfdSAndroid Build Coastguard Worker}; 266*387f9dfdSAndroid Build Coastguard Worker 267*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(dns_events); 268*387f9dfdSAndroid Build Coastguard Worker 269*387f9dfdSAndroid Build Coastguard Worker// store msghdr pointer captured on syscall entry to parse on syscall return 270*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(tbl_udp_msg_hdr, u64, struct msghdr *); 271*387f9dfdSAndroid Build Coastguard Worker 272*387f9dfdSAndroid Build Coastguard Worker// single element per-cpu array to hold the current event off the stack 273*387f9dfdSAndroid Build Coastguard WorkerBPF_PERCPU_ARRAY(dns_data,struct dns_data_t,1); 274*387f9dfdSAndroid Build Coastguard Worker 275*387f9dfdSAndroid Build Coastguard Workerint trace_udp_recvmsg(struct pt_regs *ctx) 276*387f9dfdSAndroid Build Coastguard Worker{ 277*387f9dfdSAndroid Build Coastguard Worker __u64 pid_tgid = bpf_get_current_pid_tgid(); 278*387f9dfdSAndroid Build Coastguard Worker struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx); 279*387f9dfdSAndroid Build Coastguard Worker struct inet_sock *is = inet_sk(sk); 280*387f9dfdSAndroid Build Coastguard Worker 281*387f9dfdSAndroid Build Coastguard Worker // only grab port 53 packets, 13568 is ntohs(53) 282*387f9dfdSAndroid Build Coastguard Worker if (is->inet_dport == 13568) { 283*387f9dfdSAndroid Build Coastguard Worker struct msghdr *msghdr = (struct msghdr *)PT_REGS_PARM2(ctx); 284*387f9dfdSAndroid Build Coastguard Worker tbl_udp_msg_hdr.update(&pid_tgid, &msghdr); 285*387f9dfdSAndroid Build Coastguard Worker } 286*387f9dfdSAndroid Build Coastguard Worker return 0; 287*387f9dfdSAndroid Build Coastguard Worker} 288*387f9dfdSAndroid Build Coastguard Worker 289*387f9dfdSAndroid Build Coastguard Workerint trace_udp_ret_recvmsg(struct pt_regs *ctx) 290*387f9dfdSAndroid Build Coastguard Worker{ 291*387f9dfdSAndroid Build Coastguard Worker __u64 pid_tgid = bpf_get_current_pid_tgid(); 292*387f9dfdSAndroid Build Coastguard Worker u32 zero = 0; 293*387f9dfdSAndroid Build Coastguard Worker struct msghdr **msgpp = tbl_udp_msg_hdr.lookup(&pid_tgid); 294*387f9dfdSAndroid Build Coastguard Worker if (msgpp == 0) 295*387f9dfdSAndroid Build Coastguard Worker return 0; 296*387f9dfdSAndroid Build Coastguard Worker 297*387f9dfdSAndroid Build Coastguard Worker struct msghdr *msghdr = (struct msghdr *)*msgpp; 298*387f9dfdSAndroid Build Coastguard Worker if (msghdr->msg_iter.TYPE_FIELD != ITER_IOVEC) 299*387f9dfdSAndroid Build Coastguard Worker goto delete_and_return; 300*387f9dfdSAndroid Build Coastguard Worker 301*387f9dfdSAndroid Build Coastguard Worker int copied = (int)PT_REGS_RC(ctx); 302*387f9dfdSAndroid Build Coastguard Worker if (copied < 0) 303*387f9dfdSAndroid Build Coastguard Worker goto delete_and_return; 304*387f9dfdSAndroid Build Coastguard Worker size_t buflen = (size_t)copied; 305*387f9dfdSAndroid Build Coastguard Worker 306*387f9dfdSAndroid Build Coastguard Worker if (buflen > msghdr->msg_iter.iov->iov_len) 307*387f9dfdSAndroid Build Coastguard Worker goto delete_and_return; 308*387f9dfdSAndroid Build Coastguard Worker 309*387f9dfdSAndroid Build Coastguard Worker if (buflen > MAX_PKT) 310*387f9dfdSAndroid Build Coastguard Worker buflen = MAX_PKT; 311*387f9dfdSAndroid Build Coastguard Worker 312*387f9dfdSAndroid Build Coastguard Worker struct dns_data_t *data = dns_data.lookup(&zero); 313*387f9dfdSAndroid Build Coastguard Worker if (!data) // this should never happen, just making the verifier happy 314*387f9dfdSAndroid Build Coastguard Worker return 0; 315*387f9dfdSAndroid Build Coastguard Worker 316*387f9dfdSAndroid Build Coastguard Worker void *iovbase = msghdr->msg_iter.iov->iov_base; 317*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read(data->pkt, buflen, iovbase); 318*387f9dfdSAndroid Build Coastguard Worker dns_events.perf_submit(ctx, data, buflen); 319*387f9dfdSAndroid Build Coastguard Worker 320*387f9dfdSAndroid Build Coastguard Workerdelete_and_return: 321*387f9dfdSAndroid Build Coastguard Worker tbl_udp_msg_hdr.delete(&pid_tgid); 322*387f9dfdSAndroid Build Coastguard Worker return 0; 323*387f9dfdSAndroid Build Coastguard Worker} 324*387f9dfdSAndroid Build Coastguard Worker 325*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/udp.h> 326*387f9dfdSAndroid Build Coastguard Worker 327*387f9dfdSAndroid Build Coastguard Workerint trace_udpv6_recvmsg(struct pt_regs *ctx) 328*387f9dfdSAndroid Build Coastguard Worker{ 329*387f9dfdSAndroid Build Coastguard Worker struct sk_buff *skb = (struct sk_buff *)PT_REGS_PARM2(ctx); 330*387f9dfdSAndroid Build Coastguard Worker struct udphdr *hdr = (void*)skb->head + skb->transport_header; 331*387f9dfdSAndroid Build Coastguard Worker struct dns_data_t *event; 332*387f9dfdSAndroid Build Coastguard Worker int zero = 0; 333*387f9dfdSAndroid Build Coastguard Worker void *data; 334*387f9dfdSAndroid Build Coastguard Worker 335*387f9dfdSAndroid Build Coastguard Worker /* hex(53) = 0x0035, htons(0x0035) = 0x3500 */ 336*387f9dfdSAndroid Build Coastguard Worker if (hdr->source != 0x3500) 337*387f9dfdSAndroid Build Coastguard Worker return 0; 338*387f9dfdSAndroid Build Coastguard Worker 339*387f9dfdSAndroid Build Coastguard Worker /* skip UDP header */ 340*387f9dfdSAndroid Build Coastguard Worker data = skb->data + 8; 341*387f9dfdSAndroid Build Coastguard Worker 342*387f9dfdSAndroid Build Coastguard Worker event = dns_data.lookup(&zero); 343*387f9dfdSAndroid Build Coastguard Worker if (!event) 344*387f9dfdSAndroid Build Coastguard Worker return 0; 345*387f9dfdSAndroid Build Coastguard Worker 346*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read(event->pkt, sizeof(event->pkt), data); 347*387f9dfdSAndroid Build Coastguard Worker dns_events.perf_submit(ctx, event, sizeof(*event)); 348*387f9dfdSAndroid Build Coastguard Worker return 0; 349*387f9dfdSAndroid Build Coastguard Worker} 350*387f9dfdSAndroid Build Coastguard Worker""" 351*387f9dfdSAndroid Build Coastguard Worker 352*387f9dfdSAndroid Build Coastguard Workerif args.count and args.dns: 353*387f9dfdSAndroid Build Coastguard Worker print("Error: you may not specify -d/--dns with -c/--count.") 354*387f9dfdSAndroid Build Coastguard Worker exit() 355*387f9dfdSAndroid Build Coastguard Worker 356*387f9dfdSAndroid Build Coastguard Worker# code substitutions 357*387f9dfdSAndroid Build Coastguard Workerif args.count: 358*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace("IPV4_CODE", struct_init['ipv4']['count']) 359*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace("IPV6_CODE", struct_init['ipv6']['count']) 360*387f9dfdSAndroid Build Coastguard Workerelse: 361*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace("IPV4_CODE", struct_init['ipv4']['trace']) 362*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace("IPV6_CODE", struct_init['ipv6']['trace']) 363*387f9dfdSAndroid Build Coastguard Worker 364*387f9dfdSAndroid Build Coastguard Workerif args.pid: 365*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER_PID', 366*387f9dfdSAndroid Build Coastguard Worker 'if (pid != %s) { return 0; }' % args.pid) 367*387f9dfdSAndroid Build Coastguard Workerif args.port: 368*387f9dfdSAndroid Build Coastguard Worker dports = [int(dport) for dport in args.port.split(',')] 369*387f9dfdSAndroid Build Coastguard Worker dports_if = ' && '.join(['dport != %d' % ntohs(dport) for dport in dports]) 370*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER_PORT', 371*387f9dfdSAndroid Build Coastguard Worker 'if (%s) { currsock.delete(&tid); return 0; }' % dports_if) 372*387f9dfdSAndroid Build Coastguard Workerif args.ipv4: 373*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER_FAMILY', 374*387f9dfdSAndroid Build Coastguard Worker 'if (ipver != 4) { return 0; }') 375*387f9dfdSAndroid Build Coastguard Workerelif args.ipv6: 376*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER_FAMILY', 377*387f9dfdSAndroid Build Coastguard Worker 'if (ipver != 6) { return 0; }') 378*387f9dfdSAndroid Build Coastguard Workerif args.uid: 379*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER_UID', 380*387f9dfdSAndroid Build Coastguard Worker 'if (uid != %s) { return 0; }' % args.uid) 381*387f9dfdSAndroid Build Coastguard Workerbpf_text = filter_by_containers(args) + bpf_text 382*387f9dfdSAndroid Build Coastguard Worker 383*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('FILTER_PID', '') 384*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('FILTER_PORT', '') 385*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('FILTER_FAMILY', '') 386*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('FILTER_UID', '') 387*387f9dfdSAndroid Build Coastguard Worker 388*387f9dfdSAndroid Build Coastguard Workerif args.dns: 389*387f9dfdSAndroid Build Coastguard Worker if BPF.kernel_struct_has_field(b'iov_iter', b'iter_type') == 1: 390*387f9dfdSAndroid Build Coastguard Worker dns_bpf_text = dns_bpf_text.replace('TYPE_FIELD', 'iter_type') 391*387f9dfdSAndroid Build Coastguard Worker else: 392*387f9dfdSAndroid Build Coastguard Worker dns_bpf_text = dns_bpf_text.replace('TYPE_FIELD', 'type') 393*387f9dfdSAndroid Build Coastguard Worker bpf_text += dns_bpf_text 394*387f9dfdSAndroid Build Coastguard Worker 395*387f9dfdSAndroid Build Coastguard Workerif debug or args.ebpf: 396*387f9dfdSAndroid Build Coastguard Worker print(bpf_text) 397*387f9dfdSAndroid Build Coastguard Worker if args.ebpf: 398*387f9dfdSAndroid Build Coastguard Worker exit() 399*387f9dfdSAndroid Build Coastguard Worker 400*387f9dfdSAndroid Build Coastguard Worker# process event 401*387f9dfdSAndroid Build Coastguard Workerdef print_ipv4_event(cpu, data, size): 402*387f9dfdSAndroid Build Coastguard Worker event = b["ipv4_events"].event(data) 403*387f9dfdSAndroid Build Coastguard Worker global start_ts 404*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 405*387f9dfdSAndroid Build Coastguard Worker if start_ts == 0: 406*387f9dfdSAndroid Build Coastguard Worker start_ts = event.ts_us 407*387f9dfdSAndroid Build Coastguard Worker printb(b"%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), nl="") 408*387f9dfdSAndroid Build Coastguard Worker if args.print_uid: 409*387f9dfdSAndroid Build Coastguard Worker printb(b"%-6d" % event.uid, nl="") 410*387f9dfdSAndroid Build Coastguard Worker dest_ip = inet_ntop(AF_INET, pack("I", event.daddr)).encode() 411*387f9dfdSAndroid Build Coastguard Worker if args.lport: 412*387f9dfdSAndroid Build Coastguard Worker printb(b"%-7d %-12.12s %-2d %-16s %-6d %-16s %-6d %s" % (event.pid, 413*387f9dfdSAndroid Build Coastguard Worker event.task, event.ip, 414*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack("I", event.saddr)).encode(), event.lport, 415*387f9dfdSAndroid Build Coastguard Worker dest_ip, event.dport, print_dns(dest_ip))) 416*387f9dfdSAndroid Build Coastguard Worker else: 417*387f9dfdSAndroid Build Coastguard Worker printb(b"%-7d %-12.12s %-2d %-16s %-16s %-6d %s" % (event.pid, 418*387f9dfdSAndroid Build Coastguard Worker event.task, event.ip, 419*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack("I", event.saddr)).encode(), 420*387f9dfdSAndroid Build Coastguard Worker dest_ip, event.dport, print_dns(dest_ip))) 421*387f9dfdSAndroid Build Coastguard Worker 422*387f9dfdSAndroid Build Coastguard Workerdef print_ipv6_event(cpu, data, size): 423*387f9dfdSAndroid Build Coastguard Worker event = b["ipv6_events"].event(data) 424*387f9dfdSAndroid Build Coastguard Worker global start_ts 425*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 426*387f9dfdSAndroid Build Coastguard Worker if start_ts == 0: 427*387f9dfdSAndroid Build Coastguard Worker start_ts = event.ts_us 428*387f9dfdSAndroid Build Coastguard Worker printb(b"%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), nl="") 429*387f9dfdSAndroid Build Coastguard Worker if args.print_uid: 430*387f9dfdSAndroid Build Coastguard Worker printb(b"%-6d" % event.uid, nl="") 431*387f9dfdSAndroid Build Coastguard Worker dest_ip = inet_ntop(AF_INET6, event.daddr).encode() 432*387f9dfdSAndroid Build Coastguard Worker if args.lport: 433*387f9dfdSAndroid Build Coastguard Worker printb(b"%-7d %-12.12s %-2d %-16s %-6d %-16s %-6d %s" % (event.pid, 434*387f9dfdSAndroid Build Coastguard Worker event.task, event.ip, 435*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET6, event.saddr).encode(), event.lport, 436*387f9dfdSAndroid Build Coastguard Worker dest_ip, event.dport, print_dns(dest_ip))) 437*387f9dfdSAndroid Build Coastguard Worker else: 438*387f9dfdSAndroid Build Coastguard Worker printb(b"%-7d %-12.12s %-2d %-16s %-16s %-6d %s" % (event.pid, 439*387f9dfdSAndroid Build Coastguard Worker event.task, event.ip, 440*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET6, event.saddr).encode(), 441*387f9dfdSAndroid Build Coastguard Worker dest_ip, event.dport, print_dns(dest_ip))) 442*387f9dfdSAndroid Build Coastguard Worker 443*387f9dfdSAndroid Build Coastguard Workerdef depict_cnt(counts_tab, l3prot='ipv4'): 444*387f9dfdSAndroid Build Coastguard Worker for k, v in sorted(counts_tab.items(), 445*387f9dfdSAndroid Build Coastguard Worker key=lambda counts: counts[1].value, reverse=True): 446*387f9dfdSAndroid Build Coastguard Worker depict_key = "" 447*387f9dfdSAndroid Build Coastguard Worker if l3prot == 'ipv4': 448*387f9dfdSAndroid Build Coastguard Worker depict_key = "%-25s %-25s %-20s" % \ 449*387f9dfdSAndroid Build Coastguard Worker ((inet_ntop(AF_INET, pack('I', k.saddr))), 450*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET, pack('I', k.daddr)), k.dport) 451*387f9dfdSAndroid Build Coastguard Worker else: 452*387f9dfdSAndroid Build Coastguard Worker depict_key = "%-25s %-25s %-20s" % \ 453*387f9dfdSAndroid Build Coastguard Worker ((inet_ntop(AF_INET6, k.saddr)), 454*387f9dfdSAndroid Build Coastguard Worker inet_ntop(AF_INET6, k.daddr), k.dport) 455*387f9dfdSAndroid Build Coastguard Worker 456*387f9dfdSAndroid Build Coastguard Worker print("%s %-10d" % (depict_key, v.value)) 457*387f9dfdSAndroid Build Coastguard Worker 458*387f9dfdSAndroid Build Coastguard Workerdef print_dns(dest_ip): 459*387f9dfdSAndroid Build Coastguard Worker if not args.dns: 460*387f9dfdSAndroid Build Coastguard Worker return b"" 461*387f9dfdSAndroid Build Coastguard Worker 462*387f9dfdSAndroid Build Coastguard Worker dnsname, timestamp = dns_cache.get(dest_ip, (None, None)) 463*387f9dfdSAndroid Build Coastguard Worker if timestamp is not None: 464*387f9dfdSAndroid Build Coastguard Worker diff = datetime.now() - timestamp 465*387f9dfdSAndroid Build Coastguard Worker diff = float(diff.seconds) * 1000 + float(diff.microseconds) / 1000 466*387f9dfdSAndroid Build Coastguard Worker else: 467*387f9dfdSAndroid Build Coastguard Worker diff = 0 468*387f9dfdSAndroid Build Coastguard Worker if dnsname is None: 469*387f9dfdSAndroid Build Coastguard Worker dnsname = b"No DNS Query" 470*387f9dfdSAndroid Build Coastguard Worker if dest_ip == b"127.0.0.1" or dest_ip == b"::1": 471*387f9dfdSAndroid Build Coastguard Worker dnsname = b"localhost" 472*387f9dfdSAndroid Build Coastguard Worker retval = b"%s" % dnsname 473*387f9dfdSAndroid Build Coastguard Worker if diff > DELAY_DNS: 474*387f9dfdSAndroid Build Coastguard Worker retval += b" (%.3fms)" % diff 475*387f9dfdSAndroid Build Coastguard Worker return retval 476*387f9dfdSAndroid Build Coastguard Worker 477*387f9dfdSAndroid Build Coastguard Workerif args.dns: 478*387f9dfdSAndroid Build Coastguard Worker try: 479*387f9dfdSAndroid Build Coastguard Worker import dnslib 480*387f9dfdSAndroid Build Coastguard Worker from cachetools import TTLCache 481*387f9dfdSAndroid Build Coastguard Worker except ImportError: 482*387f9dfdSAndroid Build Coastguard Worker print("Error: The python packages dnslib and cachetools are required " 483*387f9dfdSAndroid Build Coastguard Worker "to use the -d/--dns option.") 484*387f9dfdSAndroid Build Coastguard Worker print("Install this package with:") 485*387f9dfdSAndroid Build Coastguard Worker print("\t$ pip3 install dnslib cachetools") 486*387f9dfdSAndroid Build Coastguard Worker print(" or") 487*387f9dfdSAndroid Build Coastguard Worker print("\t$ sudo apt-get install python3-dnslib python3-cachetools " 488*387f9dfdSAndroid Build Coastguard Worker "(on Ubuntu 18.04+)") 489*387f9dfdSAndroid Build Coastguard Worker exit(1) 490*387f9dfdSAndroid Build Coastguard Worker 491*387f9dfdSAndroid Build Coastguard Worker # 24 hours 492*387f9dfdSAndroid Build Coastguard Worker DEFAULT_TTL = 86400 493*387f9dfdSAndroid Build Coastguard Worker 494*387f9dfdSAndroid Build Coastguard Worker # Cache Size in entries 495*387f9dfdSAndroid Build Coastguard Worker DNS_CACHE_SIZE = 10240 496*387f9dfdSAndroid Build Coastguard Worker 497*387f9dfdSAndroid Build Coastguard Worker # delay in ms in which to warn users of long delay between the query 498*387f9dfdSAndroid Build Coastguard Worker # and the connect that used the IP 499*387f9dfdSAndroid Build Coastguard Worker DELAY_DNS = 100 500*387f9dfdSAndroid Build Coastguard Worker 501*387f9dfdSAndroid Build Coastguard Worker dns_cache = TTLCache(maxsize=DNS_CACHE_SIZE, ttl=DEFAULT_TTL) 502*387f9dfdSAndroid Build Coastguard Worker 503*387f9dfdSAndroid Build Coastguard Worker # process event 504*387f9dfdSAndroid Build Coastguard Worker def save_dns(cpu, data, size): 505*387f9dfdSAndroid Build Coastguard Worker event = b["dns_events"].event(data) 506*387f9dfdSAndroid Build Coastguard Worker payload = event.pkt[:size] 507*387f9dfdSAndroid Build Coastguard Worker 508*387f9dfdSAndroid Build Coastguard Worker # pass the payload to dnslib for parsing 509*387f9dfdSAndroid Build Coastguard Worker dnspkt = dnslib.DNSRecord.parse(payload) 510*387f9dfdSAndroid Build Coastguard Worker # lets only look at responses 511*387f9dfdSAndroid Build Coastguard Worker if dnspkt.header.qr != 1: 512*387f9dfdSAndroid Build Coastguard Worker return 513*387f9dfdSAndroid Build Coastguard Worker # must be some questions in there 514*387f9dfdSAndroid Build Coastguard Worker if dnspkt.header.q != 1: 515*387f9dfdSAndroid Build Coastguard Worker return 516*387f9dfdSAndroid Build Coastguard Worker # make sure there are answers 517*387f9dfdSAndroid Build Coastguard Worker if dnspkt.header.a == 0 and dnspkt.header.aa == 0: 518*387f9dfdSAndroid Build Coastguard Worker return 519*387f9dfdSAndroid Build Coastguard Worker 520*387f9dfdSAndroid Build Coastguard Worker # lop off the trailing . 521*387f9dfdSAndroid Build Coastguard Worker question = ("%s" % dnspkt.q.qname)[:-1].encode('utf-8') 522*387f9dfdSAndroid Build Coastguard Worker 523*387f9dfdSAndroid Build Coastguard Worker for answer in dnspkt.rr: 524*387f9dfdSAndroid Build Coastguard Worker # skip all but A and AAAA records 525*387f9dfdSAndroid Build Coastguard Worker if answer.rtype == 1 or answer.rtype == 28: 526*387f9dfdSAndroid Build Coastguard Worker dns_cache[str(answer.rdata).encode('utf-8')] = (question, 527*387f9dfdSAndroid Build Coastguard Worker datetime.now()) 528*387f9dfdSAndroid Build Coastguard Worker 529*387f9dfdSAndroid Build Coastguard Worker# initialize BPF 530*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text) 531*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_entry") 532*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect_entry") 533*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_return") 534*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_return") 535*387f9dfdSAndroid Build Coastguard Workerif args.dns: 536*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="udp_recvmsg", fn_name="trace_udp_recvmsg") 537*387f9dfdSAndroid Build Coastguard Worker b.attach_kretprobe(event="udp_recvmsg", fn_name="trace_udp_ret_recvmsg") 538*387f9dfdSAndroid Build Coastguard Worker b.attach_kprobe(event="udpv6_queue_rcv_one_skb", fn_name="trace_udpv6_recvmsg") 539*387f9dfdSAndroid Build Coastguard Worker 540*387f9dfdSAndroid Build Coastguard Workerprint("Tracing connect ... Hit Ctrl-C to end") 541*387f9dfdSAndroid Build Coastguard Workerif args.count: 542*387f9dfdSAndroid Build Coastguard Worker try: 543*387f9dfdSAndroid Build Coastguard Worker while True: 544*387f9dfdSAndroid Build Coastguard Worker sleep(99999999) 545*387f9dfdSAndroid Build Coastguard Worker except KeyboardInterrupt: 546*387f9dfdSAndroid Build Coastguard Worker pass 547*387f9dfdSAndroid Build Coastguard Worker 548*387f9dfdSAndroid Build Coastguard Worker # header 549*387f9dfdSAndroid Build Coastguard Worker print("\n%-25s %-25s %-20s %-10s" % ( 550*387f9dfdSAndroid Build Coastguard Worker "LADDR", "RADDR", "RPORT", "CONNECTS")) 551*387f9dfdSAndroid Build Coastguard Worker depict_cnt(b["ipv4_count"]) 552*387f9dfdSAndroid Build Coastguard Worker depict_cnt(b["ipv6_count"], l3prot='ipv6') 553*387f9dfdSAndroid Build Coastguard Worker# read events 554*387f9dfdSAndroid Build Coastguard Workerelse: 555*387f9dfdSAndroid Build Coastguard Worker # header 556*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 557*387f9dfdSAndroid Build Coastguard Worker print("%-9s" % ("TIME(s)"), end="") 558*387f9dfdSAndroid Build Coastguard Worker if args.print_uid: 559*387f9dfdSAndroid Build Coastguard Worker print("%-6s" % ("UID"), end="") 560*387f9dfdSAndroid Build Coastguard Worker if args.lport: 561*387f9dfdSAndroid Build Coastguard Worker print("%-7s %-12s %-2s %-16s %-6s %-16s %-6s" % ("PID", "COMM", "IP", "SADDR", 562*387f9dfdSAndroid Build Coastguard Worker "LPORT", "DADDR", "DPORT"), end="") 563*387f9dfdSAndroid Build Coastguard Worker else: 564*387f9dfdSAndroid Build Coastguard Worker print("%-7s %-12s %-2s %-16s %-16s %-6s" % ("PID", "COMM", "IP", "SADDR", 565*387f9dfdSAndroid Build Coastguard Worker "DADDR", "DPORT"), end="") 566*387f9dfdSAndroid Build Coastguard Worker if args.dns: 567*387f9dfdSAndroid Build Coastguard Worker print(" QUERY") 568*387f9dfdSAndroid Build Coastguard Worker else: 569*387f9dfdSAndroid Build Coastguard Worker print() 570*387f9dfdSAndroid Build Coastguard Worker 571*387f9dfdSAndroid Build Coastguard Worker start_ts = 0 572*387f9dfdSAndroid Build Coastguard Worker 573*387f9dfdSAndroid Build Coastguard Worker # read events 574*387f9dfdSAndroid Build Coastguard Worker b["ipv4_events"].open_perf_buffer(print_ipv4_event) 575*387f9dfdSAndroid Build Coastguard Worker b["ipv6_events"].open_perf_buffer(print_ipv6_event) 576*387f9dfdSAndroid Build Coastguard Worker if args.dns: 577*387f9dfdSAndroid Build Coastguard Worker b["dns_events"].open_perf_buffer(save_dns) 578*387f9dfdSAndroid Build Coastguard Worker while True: 579*387f9dfdSAndroid Build Coastguard Worker try: 580*387f9dfdSAndroid Build Coastguard Worker b.perf_buffer_poll() 581*387f9dfdSAndroid Build Coastguard Worker except KeyboardInterrupt: 582*387f9dfdSAndroid Build Coastguard Worker exit() 583