blob: 4621e9f699f0221b7837735cf7f1f47b88399b16 [file] [log] [blame]
Alexey Ivanovcc01a9c2019-01-16 09:50:46 -08001#!/usr/bin/python
Adrian Lopezd496d5c2016-08-16 17:49:49 +02002#
jeromemarchand8b17dc32018-08-04 07:09:36 +02003# sslsniff Captures data on read/recv or write/send functions of OpenSSL,
4# GnuTLS and NSS
Adrian Lopezd496d5c2016-08-16 17:49:49 +02005# For Linux, uses BCC, eBPF.
6#
Slava Bacherikov91a79832021-11-21 15:31:49 +02007# USAGE: sslsniff.py [-h] [-p PID] [-u UID] [-x] [-c COMM] [-o] [-g] [-n] [-d]
Tao Xuba860862022-01-28 03:28:41 +08008# [--hexdump] [--max-buffer-size SIZE] [-l] [--handshake]
Adrian Lopezd9cc3de2016-08-17 14:08:08 +02009#
Adrian Lopezd496d5c2016-08-16 17:49:49 +020010# Licensed under the Apache License, Version 2.0 (the "License")
11#
12# 12-Aug-2016 Adrian Lopez Created this.
13# 13-Aug-2016 Mark Drayton Fix SSL_Read
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020014# 17-Aug-2016 Adrian Lopez Capture GnuTLS and add options
15#
Adrian Lopezd496d5c2016-08-16 17:49:49 +020016
17from __future__ import print_function
Adrian Lopezd496d5c2016-08-16 17:49:49 +020018from bcc import BPF
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020019import argparse
Matthias Hörmann1b7aab12020-07-03 13:54:24 +020020import binascii
21import textwrap
Slava Bacherikov8db99af2022-02-09 23:48:50 +020022import os.path
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020023
24# arguments
25examples = """examples:
26 ./sslsniff # sniff OpenSSL and GnuTLS functions
27 ./sslsniff -p 181 # sniff PID 181 only
Slava Bacherikov91a79832021-11-21 15:31:49 +020028 ./sslsniff -u 1000 # sniff only UID 1000
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020029 ./sslsniff -c curl # sniff curl command only
30 ./sslsniff --no-openssl # don't show OpenSSL calls
31 ./sslsniff --no-gnutls # don't show GnuTLS calls
jeromemarchand8b17dc32018-08-04 07:09:36 +020032 ./sslsniff --no-nss # don't show NSS calls
Matthias Hörmannd40c3a72020-07-03 14:31:32 +020033 ./sslsniff --hexdump # show data as hex instead of trying to decode it as UTF-8
Slava Bacherikov91a79832021-11-21 15:31:49 +020034 ./sslsniff -x # show process UID and TID
Tao Xuba860862022-01-28 03:28:41 +080035 ./sslsniff -l # show function latency
36 ./sslsniff -l --handshake # show SSL handshake latency
Slava Bacherikov8db99af2022-02-09 23:48:50 +020037 ./sslsniff --extra-lib openssl:/path/libssl.so.1.1 # sniff extra library
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020038"""
Slava Bacherikov8db99af2022-02-09 23:48:50 +020039
40
41def ssllib_type(input_str):
42 valid_types = frozenset(['openssl', 'gnutls', 'nss'])
43
44 try:
45 lib_type, lib_path = input_str.split(':', 1)
46 except ValueError:
47 raise argparse.ArgumentTypeError("Invalid SSL library param: %r" % input_str)
48
49 if lib_type not in valid_types:
50 raise argparse.ArgumentTypeError("Invalid SSL library type: %r" % lib_type)
51
52 if not os.path.isfile(lib_path):
53 raise argparse.ArgumentTypeError("Invalid library path: %r" % lib_path)
54
55 return lib_type, lib_path
56
57
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020058parser = argparse.ArgumentParser(
59 description="Sniff SSL data",
60 formatter_class=argparse.RawDescriptionHelpFormatter,
61 epilog=examples)
htbegin5ac5d6e2017-05-24 22:53:17 +080062parser.add_argument("-p", "--pid", type=int, help="sniff this PID only.")
Slava Bacherikov91a79832021-11-21 15:31:49 +020063parser.add_argument("-u", "--uid", type=int, default=None,
64 help="sniff this UID only.")
65parser.add_argument("-x", "--extra", action="store_true",
66 help="show extra fields (UID, TID)")
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020067parser.add_argument("-c", "--comm",
68 help="sniff only commands matching string.")
69parser.add_argument("-o", "--no-openssl", action="store_false", dest="openssl",
70 help="do not show OpenSSL calls.")
71parser.add_argument("-g", "--no-gnutls", action="store_false", dest="gnutls",
72 help="do not show GnuTLS calls.")
jeromemarchand8b17dc32018-08-04 07:09:36 +020073parser.add_argument("-n", "--no-nss", action="store_false", dest="nss",
74 help="do not show NSS calls.")
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020075parser.add_argument('-d', '--debug', dest='debug', action='count', default=0,
76 help='debug mode.')
Nathan Scottcf0792f2018-02-02 16:56:50 +110077parser.add_argument("--ebpf", action="store_true",
78 help=argparse.SUPPRESS)
Matthias Hörmannd91b31a2020-07-06 09:38:39 +020079parser.add_argument("--hexdump", action="store_true", dest="hexdump",
80 help="show data as hexdump instead of trying to decode it as UTF-8")
Slava Bacherikov91a79832021-11-21 15:31:49 +020081parser.add_argument('--max-buffer-size', type=int, default=8192,
82 help='Size of captured buffer')
Tao Xuba860862022-01-28 03:28:41 +080083parser.add_argument("-l", "--latency", action="store_true",
84 help="show function latency")
85parser.add_argument("--handshake", action="store_true",
86 help="show SSL handshake latency, enabled only if latency option is on.")
Slava Bacherikov8db99af2022-02-09 23:48:50 +020087parser.add_argument("--extra-lib", type=ssllib_type, action='append',
88 help="Intercept calls from extra library (format: lib_type:lib_path)")
Adrian Lopezd9cc3de2016-08-17 14:08:08 +020089args = parser.parse_args()
90
Adrian Lopezd496d5c2016-08-16 17:49:49 +020091
92prog = """
93#include <linux/ptrace.h>
94#include <linux/sched.h> /* For TASK_COMM_LEN */
95
Slava Bacherikov91a79832021-11-21 15:31:49 +020096#define MAX_BUF_SIZE __MAX_BUF_SIZE__
97
Adrian Lopezd496d5c2016-08-16 17:49:49 +020098struct probe_SSL_data_t {
99 u64 timestamp_ns;
Tao Xuba860862022-01-28 03:28:41 +0800100 u64 delta_ns;
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200101 u32 pid;
Slava Bacherikov91a79832021-11-21 15:31:49 +0200102 u32 tid;
103 u32 uid;
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200104 u32 len;
Slava Bacherikov91a79832021-11-21 15:31:49 +0200105 int buf_filled;
Tao Xuba860862022-01-28 03:28:41 +0800106 int rw;
Slava Bacherikov91a79832021-11-21 15:31:49 +0200107 char comm[TASK_COMM_LEN];
108 u8 buf[MAX_BUF_SIZE];
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200109};
110
Slava Bacherikov91a79832021-11-21 15:31:49 +0200111#define BASE_EVENT_SIZE ((size_t)(&((struct probe_SSL_data_t*)0)->buf))
112#define EVENT_SIZE(X) (BASE_EVENT_SIZE + ((size_t)(X)))
113
Slava Bacherikov91a79832021-11-21 15:31:49 +0200114BPF_PERCPU_ARRAY(ssl_data, struct probe_SSL_data_t, 1);
Tao Xuba860862022-01-28 03:28:41 +0800115BPF_PERF_OUTPUT(perf_SSL_rw);
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200116
Tao Xuba860862022-01-28 03:28:41 +0800117BPF_HASH(start_ns, u32);
118BPF_HASH(bufs, u32, u64);
119
120int probe_SSL_rw_enter(struct pt_regs *ctx, void *ssl, void *buf, int num) {
Slava Bacherikov91a79832021-11-21 15:31:49 +0200121 int ret;
122 u32 zero = 0;
Hengqi Chen151fe192021-05-16 17:18:27 +0800123 u64 pid_tgid = bpf_get_current_pid_tgid();
124 u32 pid = pid_tgid >> 32;
Slava Bacherikov91a79832021-11-21 15:31:49 +0200125 u32 tid = pid_tgid;
126 u32 uid = bpf_get_current_uid_gid();
Tao Xuba860862022-01-28 03:28:41 +0800127 u64 ts = bpf_ktime_get_ns();
Hengqi Chen151fe192021-05-16 17:18:27 +0800128
Slava Bacherikov91a79832021-11-21 15:31:49 +0200129 PID_FILTER
130 UID_FILTER
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200131
Hengqi Chen151fe192021-05-16 17:18:27 +0800132 bufs.update(&tid, (u64*)&buf);
Tao Xuba860862022-01-28 03:28:41 +0800133 start_ns.update(&tid, &ts);
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200134 return 0;
135}
136
Tao Xuba860862022-01-28 03:28:41 +0800137static int SSL_exit(struct pt_regs *ctx, int rw) {
138 int ret;
Slava Bacherikov91a79832021-11-21 15:31:49 +0200139 u32 zero = 0;
Hengqi Chen151fe192021-05-16 17:18:27 +0800140 u64 pid_tgid = bpf_get_current_pid_tgid();
141 u32 pid = pid_tgid >> 32;
142 u32 tid = (u32)pid_tgid;
Slava Bacherikov91a79832021-11-21 15:31:49 +0200143 u32 uid = bpf_get_current_uid_gid();
Tao Xuba860862022-01-28 03:28:41 +0800144 u64 ts = bpf_ktime_get_ns();
Hengqi Chen151fe192021-05-16 17:18:27 +0800145
Slava Bacherikov91a79832021-11-21 15:31:49 +0200146 PID_FILTER
147 UID_FILTER
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200148
Hengqi Chen151fe192021-05-16 17:18:27 +0800149 u64 *bufp = bufs.lookup(&tid);
Slava Bacherikov91a79832021-11-21 15:31:49 +0200150 if (bufp == 0)
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200151 return 0;
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200152
Tao Xuba860862022-01-28 03:28:41 +0800153 u64 *tsp = start_ns.lookup(&tid);
154 if (tsp == 0)
155 return 0;
156
Slava Bacherikov91a79832021-11-21 15:31:49 +0200157 int len = PT_REGS_RC(ctx);
Tao Xuba860862022-01-28 03:28:41 +0800158 if (len <= 0) // no data
Slava Bacherikov91a79832021-11-21 15:31:49 +0200159 return 0;
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200160
Slava Bacherikov91a79832021-11-21 15:31:49 +0200161 struct probe_SSL_data_t *data = ssl_data.lookup(&zero);
162 if (!data)
163 return 0;
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200164
Tao Xuba860862022-01-28 03:28:41 +0800165 data->timestamp_ns = ts;
166 data->delta_ns = ts - *tsp;
Slava Bacherikov91a79832021-11-21 15:31:49 +0200167 data->pid = pid;
168 data->tid = tid;
169 data->uid = uid;
170 data->len = (u32)len;
171 data->buf_filled = 0;
Tao Xuba860862022-01-28 03:28:41 +0800172 data->rw = rw;
Slava Bacherikov91a79832021-11-21 15:31:49 +0200173 u32 buf_copy_size = min((size_t)MAX_BUF_SIZE, (size_t)len);
174
175 bpf_get_current_comm(&data->comm, sizeof(data->comm));
176
177 if (bufp != 0)
178 ret = bpf_probe_read_user(&data->buf, buf_copy_size, (char *)*bufp);
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200179
Hengqi Chen151fe192021-05-16 17:18:27 +0800180 bufs.delete(&tid);
Tao Xuba860862022-01-28 03:28:41 +0800181 start_ns.delete(&tid);
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200182
Slava Bacherikov91a79832021-11-21 15:31:49 +0200183 if (!ret)
184 data->buf_filled = 1;
185 else
186 buf_copy_size = 0;
187
Tao Xuba860862022-01-28 03:28:41 +0800188 perf_SSL_rw.perf_submit(ctx, data, EVENT_SIZE(buf_copy_size));
189 return 0;
190}
191
192int probe_SSL_read_exit(struct pt_regs *ctx) {
193 return (SSL_exit(ctx, 0));
194}
195
196int probe_SSL_write_exit(struct pt_regs *ctx) {
197 return (SSL_exit(ctx, 1));
198}
199
200BPF_PERF_OUTPUT(perf_SSL_do_handshake);
201
202int probe_SSL_do_handshake_enter(struct pt_regs *ctx, void *ssl) {
203 u64 pid_tgid = bpf_get_current_pid_tgid();
204 u32 pid = pid_tgid >> 32;
205 u32 tid = (u32)pid_tgid;
206 u64 ts = bpf_ktime_get_ns();
207
208 PID_FILTER
209 UID_FILTER
210
211 start_ns.update(&tid, &ts);
212 return 0;
213}
214
215int probe_SSL_do_handshake_exit(struct pt_regs *ctx) {
216 u32 zero = 0;
217 u64 pid_tgid = bpf_get_current_pid_tgid();
218 u32 pid = pid_tgid >> 32;
219 u32 tid = (u32)pid_tgid;
220 u32 uid = bpf_get_current_uid_gid();
221 u64 ts = bpf_ktime_get_ns();
222 int ret;
223
224 PID_FILTER
225 UID_FILTER
226
227 u64 *tsp = start_ns.lookup(&tid);
228 if (tsp == 0)
229 return 0;
230
231 ret = PT_REGS_RC(ctx);
232 if (ret <= 0) // handshake failed
233 return 0;
234
235 struct probe_SSL_data_t *data = ssl_data.lookup(&zero);
236 if (!data)
237 return 0;
238
239 data->timestamp_ns = ts;
240 data->delta_ns = ts - *tsp;
241 data->pid = pid;
242 data->tid = tid;
243 data->uid = uid;
244 data->len = ret;
245 data->buf_filled = 0;
246 data->rw = 2;
247 bpf_get_current_comm(&data->comm, sizeof(data->comm));
248 start_ns.delete(&tid);
249
250 perf_SSL_do_handshake.perf_submit(ctx, data, EVENT_SIZE(0));
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200251 return 0;
252}
253"""
254
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200255if args.pid:
Slava Bacherikov91a79832021-11-21 15:31:49 +0200256 prog = prog.replace('PID_FILTER', 'if (pid != %d) { return 0; }' % args.pid)
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200257else:
Slava Bacherikov91a79832021-11-21 15:31:49 +0200258 prog = prog.replace('PID_FILTER', '')
259
260if args.uid is not None:
261 prog = prog.replace('UID_FILTER', 'if (uid != %d) { return 0; }' % args.uid)
262else:
263 prog = prog.replace('UID_FILTER', '')
264
265prog = prog.replace('__MAX_BUF_SIZE__', str(args.max_buffer_size))
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200266
Nathan Scottcf0792f2018-02-02 16:56:50 +1100267if args.debug or args.ebpf:
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200268 print(prog)
Nathan Scottcf0792f2018-02-02 16:56:50 +1100269 if args.ebpf:
270 exit()
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200271
272
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200273b = BPF(text=prog)
274
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200275# It looks like SSL_read's arguments aren't available in a return probe so you
276# need to stash the buffer address in a map on the function entry and read it
277# on its exit (Mark Drayton)
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200278#
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200279def attach_openssl(lib):
280 b.attach_uprobe(name=lib, sym="SSL_write",
Tao Xuba860862022-01-28 03:28:41 +0800281 fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200282 b.attach_uretprobe(name=lib, sym="SSL_write",
Tao Xuba860862022-01-28 03:28:41 +0800283 fn_name="probe_SSL_write_exit", pid=args.pid or -1)
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200284 b.attach_uprobe(name=lib, sym="SSL_read",
Tao Xuba860862022-01-28 03:28:41 +0800285 fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200286 b.attach_uretprobe(name=lib, sym="SSL_read",
Paul Chaignond73c58f2017-01-21 14:25:41 +0100287 fn_name="probe_SSL_read_exit", pid=args.pid or -1)
Tao Xuba860862022-01-28 03:28:41 +0800288 if args.latency and args.handshake:
289 b.attach_uprobe(name="ssl", sym="SSL_do_handshake",
290 fn_name="probe_SSL_do_handshake_enter", pid=args.pid or -1)
291 b.attach_uretprobe(name="ssl", sym="SSL_do_handshake",
292 fn_name="probe_SSL_do_handshake_exit", pid=args.pid or -1)
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200293
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200294def attach_gnutls(lib):
295 b.attach_uprobe(name=lib, sym="gnutls_record_send",
Tao Xuba860862022-01-28 03:28:41 +0800296 fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200297 b.attach_uretprobe(name=lib, sym="gnutls_record_send",
Tao Xuba860862022-01-28 03:28:41 +0800298 fn_name="probe_SSL_write_exit", pid=args.pid or -1)
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200299 b.attach_uprobe(name=lib, sym="gnutls_record_recv",
Tao Xuba860862022-01-28 03:28:41 +0800300 fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200301 b.attach_uretprobe(name=lib, sym="gnutls_record_recv",
Paul Chaignond73c58f2017-01-21 14:25:41 +0100302 fn_name="probe_SSL_read_exit", pid=args.pid or -1)
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200303
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200304def attach_nss(lib):
305 b.attach_uprobe(name=lib, sym="PR_Write",
306 fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
307 b.attach_uretprobe(name=lib, sym="PR_Write",
308 fn_name="probe_SSL_write_exit", pid=args.pid or -1)
309 b.attach_uprobe(name=lib, sym="PR_Send",
310 fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
311 b.attach_uretprobe(name=lib, sym="PR_Send",
312 fn_name="probe_SSL_write_exit", pid=args.pid or -1)
313 b.attach_uprobe(name=lib, sym="PR_Read",
314 fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
315 b.attach_uretprobe(name=lib, sym="PR_Read",
316 fn_name="probe_SSL_read_exit", pid=args.pid or -1)
317 b.attach_uprobe(name=lib, sym="PR_Recv",
318 fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
319 b.attach_uretprobe(name=lib, sym="PR_Recv",
320 fn_name="probe_SSL_read_exit", pid=args.pid or -1)
321
322
323LIB_TRACERS = {
324 "openssl": attach_openssl,
325 "gnutls": attach_gnutls,
326 "nss": attach_nss,
327}
328
329
330if args.openssl:
331 attach_openssl("ssl")
332if args.gnutls:
333 attach_gnutls("gnutls")
jeromemarchand8b17dc32018-08-04 07:09:36 +0200334if args.nss:
Slava Bacherikov8db99af2022-02-09 23:48:50 +0200335 attach_nss("nspr4")
336
337
338if args.extra_lib:
339 for lib_type, lib_path in args.extra_lib:
340 LIB_TRACERS[lib_type](lib_path)
jeromemarchand8b17dc32018-08-04 07:09:36 +0200341
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200342# define output data structure in Python
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200343
344
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200345# header
xingfeng251003e49482022-03-17 13:07:16 +0800346header = "%-12s %-18s %-16s %-7s %-7s" % ("FUNC", "TIME(s)", "COMM", "PID", "LEN")
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200347
Slava Bacherikov91a79832021-11-21 15:31:49 +0200348if args.extra:
349 header += " %-7s %-7s" % ("UID", "TID")
350
Tao Xuba860862022-01-28 03:28:41 +0800351if args.latency:
352 header += " %-7s" % ("LAT(ms)")
353
Slava Bacherikov91a79832021-11-21 15:31:49 +0200354print(header)
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200355# process event
356start = 0
357
Tao Xuba860862022-01-28 03:28:41 +0800358def print_event_rw(cpu, data, size):
359 print_event(cpu, data, size, "perf_SSL_rw")
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200360
Tao Xuba860862022-01-28 03:28:41 +0800361def print_event_handshake(cpu, data, size):
362 print_event(cpu, data, size, "perf_SSL_do_handshake")
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200363
Tao Xuba860862022-01-28 03:28:41 +0800364def print_event(cpu, data, size, evt):
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200365 global start
Xiaozhou Liu51d62d32019-02-15 13:03:05 +0800366 event = b[evt].event(data)
Slava Bacherikov91a79832021-11-21 15:31:49 +0200367 if event.len <= args.max_buffer_size:
368 buf_size = event.len
369 else:
370 buf_size = args.max_buffer_size
371
372 if event.buf_filled == 1:
373 buf = bytearray(event.buf[:buf_size])
374 else:
375 buf_size = 0
376 buf = b""
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200377
378 # Filter events by command
379 if args.comm:
keyolk49fdec62020-10-08 05:45:00 +0000380 if not args.comm == event.comm.decode('utf-8', 'replace'):
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200381 return
382
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200383 if start == 0:
384 start = event.timestamp_ns
385 time_s = (float(event.timestamp_ns - start)) / 1000000000
386
Tao Xuba860862022-01-28 03:28:41 +0800387 lat_str = "%.3f" % (event.delta_ns / 1000000) if event.delta_ns else "N/A"
388
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200389 s_mark = "-" * 5 + " DATA " + "-" * 5
390
391 e_mark = "-" * 5 + " END DATA " + "-" * 5
392
Slava Bacherikov91a79832021-11-21 15:31:49 +0200393 truncated_bytes = event.len - buf_size
Adrian Lopezd9cc3de2016-08-17 14:08:08 +0200394 if truncated_bytes > 0:
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200395 e_mark = "-" * 5 + " END DATA (TRUNCATED, " + str(truncated_bytes) + \
396 " bytes lost) " + "-" * 5
397
Slava Bacherikov91a79832021-11-21 15:31:49 +0200398 base_fmt = "%(func)-12s %(time)-18.9f %(comm)-16s %(pid)-7d %(len)-6d"
399
400 if args.extra:
401 base_fmt += " %(uid)-7d %(tid)-7d"
402
Tao Xuba860862022-01-28 03:28:41 +0800403 if args.latency:
404 base_fmt += " %(lat)-7s"
405
Slava Bacherikov91a79832021-11-21 15:31:49 +0200406 fmt = ''.join([base_fmt, "\n%(begin)s\n%(data)s\n%(end)s\n\n"])
Matthias Hörmannd91b31a2020-07-06 09:38:39 +0200407 if args.hexdump:
Slava Bacherikov91a79832021-11-21 15:31:49 +0200408 unwrapped_data = binascii.hexlify(buf)
409 data = textwrap.fill(unwrapped_data.decode('utf-8', 'replace'), width=32)
Matthias Hörmannd91b31a2020-07-06 09:38:39 +0200410 else:
Slava Bacherikov91a79832021-11-21 15:31:49 +0200411 data = buf.decode('utf-8', 'replace')
412
Tao Xuba860862022-01-28 03:28:41 +0800413 rw_event = {
414 0: "READ/RECV",
415 1: "WRITE/SEND",
416 2: "HANDSHAKE"
417 }
418
Slava Bacherikov91a79832021-11-21 15:31:49 +0200419 fmt_data = {
Tao Xuba860862022-01-28 03:28:41 +0800420 'func': rw_event[event.rw],
Slava Bacherikov91a79832021-11-21 15:31:49 +0200421 'time': time_s,
Tao Xuba860862022-01-28 03:28:41 +0800422 'lat': lat_str,
Slava Bacherikov91a79832021-11-21 15:31:49 +0200423 'comm': event.comm.decode('utf-8', 'replace'),
424 'pid': event.pid,
425 'tid': event.tid,
426 'uid': event.uid,
427 'len': event.len,
428 'begin': s_mark,
429 'end': e_mark,
430 'data': data
431 }
432
Tao Xuba860862022-01-28 03:28:41 +0800433 # use base_fmt if no buf filled
434 if buf_size == 0:
435 print(base_fmt % fmt_data)
436 else:
437 print(fmt % fmt_data)
Slava Bacherikov91a79832021-11-21 15:31:49 +0200438
Tao Xuba860862022-01-28 03:28:41 +0800439b["perf_SSL_rw"].open_perf_buffer(print_event_rw)
440b["perf_SSL_do_handshake"].open_perf_buffer(print_event_handshake)
Adrian Lopezd496d5c2016-08-16 17:49:49 +0200441while 1:
Jerome Marchand51671272018-12-19 01:57:24 +0100442 try:
443 b.perf_buffer_poll()
444 except KeyboardInterrupt:
445 exit()