xref: /aosp_15_r20/external/bcc/libbpf-tools/tcprtt.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2*387f9dfdSAndroid Build Coastguard Worker // Copyright (c) 2021 Wenbo Zhang
3*387f9dfdSAndroid Build Coastguard Worker //
4*387f9dfdSAndroid Build Coastguard Worker // Based on tcprtt(8) from BCC by zhenwei pi.
5*387f9dfdSAndroid Build Coastguard Worker // 06-Aug-2021   Wenbo Zhang   Created this.
6*387f9dfdSAndroid Build Coastguard Worker #define _DEFAULT_SOURCE
7*387f9dfdSAndroid Build Coastguard Worker #include <arpa/inet.h>
8*387f9dfdSAndroid Build Coastguard Worker #include <argp.h>
9*387f9dfdSAndroid Build Coastguard Worker #include <stdio.h>
10*387f9dfdSAndroid Build Coastguard Worker #include <signal.h>
11*387f9dfdSAndroid Build Coastguard Worker #include <unistd.h>
12*387f9dfdSAndroid Build Coastguard Worker #include <time.h>
13*387f9dfdSAndroid Build Coastguard Worker #include <bpf/libbpf.h>
14*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf.h>
15*387f9dfdSAndroid Build Coastguard Worker #include "tcprtt.h"
16*387f9dfdSAndroid Build Coastguard Worker #include "tcprtt.skel.h"
17*387f9dfdSAndroid Build Coastguard Worker #include "trace_helpers.h"
18*387f9dfdSAndroid Build Coastguard Worker 
19*387f9dfdSAndroid Build Coastguard Worker static struct env {
20*387f9dfdSAndroid Build Coastguard Worker 	__u16 lport;
21*387f9dfdSAndroid Build Coastguard Worker 	__u16 rport;
22*387f9dfdSAndroid Build Coastguard Worker 	__u32 laddr;
23*387f9dfdSAndroid Build Coastguard Worker 	__u32 raddr;
24*387f9dfdSAndroid Build Coastguard Worker 	__u8 laddr_v6[IPV6_LEN];
25*387f9dfdSAndroid Build Coastguard Worker 	__u8 raddr_v6[IPV6_LEN];
26*387f9dfdSAndroid Build Coastguard Worker 	bool milliseconds;
27*387f9dfdSAndroid Build Coastguard Worker 	time_t duration;
28*387f9dfdSAndroid Build Coastguard Worker 	time_t interval;
29*387f9dfdSAndroid Build Coastguard Worker 	bool timestamp;
30*387f9dfdSAndroid Build Coastguard Worker 	bool laddr_hist;
31*387f9dfdSAndroid Build Coastguard Worker 	bool raddr_hist;
32*387f9dfdSAndroid Build Coastguard Worker 	bool extended;
33*387f9dfdSAndroid Build Coastguard Worker 	bool verbose;
34*387f9dfdSAndroid Build Coastguard Worker } env = {
35*387f9dfdSAndroid Build Coastguard Worker 	.interval = 99999999,
36*387f9dfdSAndroid Build Coastguard Worker };
37*387f9dfdSAndroid Build Coastguard Worker 
38*387f9dfdSAndroid Build Coastguard Worker static volatile bool exiting;
39*387f9dfdSAndroid Build Coastguard Worker 
40*387f9dfdSAndroid Build Coastguard Worker const char *argp_program_version = "tcprtt 0.1";
41*387f9dfdSAndroid Build Coastguard Worker const char *argp_program_bug_address =
42*387f9dfdSAndroid Build Coastguard Worker 	"https://github.com/iovisor/bcc/tree/master/libbpf-tools";
43*387f9dfdSAndroid Build Coastguard Worker const char argp_program_doc[] =
44*387f9dfdSAndroid Build Coastguard Worker "Summarize TCP RTT as a histogram.\n"
45*387f9dfdSAndroid Build Coastguard Worker "\n"
46*387f9dfdSAndroid Build Coastguard Worker "USAGE: \n"
47*387f9dfdSAndroid Build Coastguard Worker "\n"
48*387f9dfdSAndroid Build Coastguard Worker "EXAMPLES:\n"
49*387f9dfdSAndroid Build Coastguard Worker "    tcprtt            # summarize TCP RTT\n"
50*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -i 1 -d 10 # print 1 second summaries, 10 times\n"
51*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -m -T      # summarize in millisecond, and timestamps\n"
52*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -p         # filter for local port\n"
53*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -P         # filter for remote port\n"
54*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -a         # filter for local address\n"
55*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -A         # filter for remote address\n"
56*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -b         # show sockets histogram by local address\n"
57*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -B         # show sockets histogram by remote address\n"
58*387f9dfdSAndroid Build Coastguard Worker "    tcprtt -e         # show extension summary(average)\n";
59*387f9dfdSAndroid Build Coastguard Worker 
60*387f9dfdSAndroid Build Coastguard Worker static const struct argp_option opts[] = {
61*387f9dfdSAndroid Build Coastguard Worker 	{ "interval", 'i', "INTERVAL", 0, "summary interval, seconds" },
62*387f9dfdSAndroid Build Coastguard Worker 	{ "duration", 'd', "DURATION", 0, "total duration of trace, seconds" },
63*387f9dfdSAndroid Build Coastguard Worker 	{ "timestamp", 'T', NULL, 0, "include timestamp on output" },
64*387f9dfdSAndroid Build Coastguard Worker 	{ "millisecond", 'm', NULL, 0, "millisecond histogram" },
65*387f9dfdSAndroid Build Coastguard Worker 	{ "lport", 'p', "LPORT", 0, "filter for local port" },
66*387f9dfdSAndroid Build Coastguard Worker 	{ "rport", 'P', "RPORT", 0, "filter for remote port" },
67*387f9dfdSAndroid Build Coastguard Worker 	{ "laddr", 'a', "LADDR", 0, "filter for local address" },
68*387f9dfdSAndroid Build Coastguard Worker 	{ "raddr", 'A', "RADDR", 0, "filter for remote address" },
69*387f9dfdSAndroid Build Coastguard Worker 	{ "byladdr", 'b', NULL, 0,
70*387f9dfdSAndroid Build Coastguard Worker 	  "show sockets histogram by local address" },
71*387f9dfdSAndroid Build Coastguard Worker 	{ "byraddr", 'B', NULL, 0,
72*387f9dfdSAndroid Build Coastguard Worker 	  "show sockets histogram by remote address" },
73*387f9dfdSAndroid Build Coastguard Worker 	{ "extension", 'e', NULL, 0, "show extension summary(average)" },
74*387f9dfdSAndroid Build Coastguard Worker 	{ "verbose", 'v', NULL, 0, "Verbose debug output" },
75*387f9dfdSAndroid Build Coastguard Worker 	{ NULL, 'h', NULL, OPTION_HIDDEN, "Show the full help" },
76*387f9dfdSAndroid Build Coastguard Worker 	{},
77*387f9dfdSAndroid Build Coastguard Worker };
78*387f9dfdSAndroid Build Coastguard Worker 
parse_arg(int key,char * arg,struct argp_state * state)79*387f9dfdSAndroid Build Coastguard Worker static error_t parse_arg(int key, char *arg, struct argp_state *state)
80*387f9dfdSAndroid Build Coastguard Worker {
81*387f9dfdSAndroid Build Coastguard Worker 	struct in_addr addr;
82*387f9dfdSAndroid Build Coastguard Worker 	struct in6_addr addr_v6;
83*387f9dfdSAndroid Build Coastguard Worker 
84*387f9dfdSAndroid Build Coastguard Worker 	switch (key) {
85*387f9dfdSAndroid Build Coastguard Worker 	case 'h':
86*387f9dfdSAndroid Build Coastguard Worker 		argp_state_help(state, stderr, ARGP_HELP_STD_HELP);
87*387f9dfdSAndroid Build Coastguard Worker 		break;
88*387f9dfdSAndroid Build Coastguard Worker 	case 'v':
89*387f9dfdSAndroid Build Coastguard Worker 		env.verbose = true;
90*387f9dfdSAndroid Build Coastguard Worker 		break;
91*387f9dfdSAndroid Build Coastguard Worker 	case 'i':
92*387f9dfdSAndroid Build Coastguard Worker 		errno = 0;
93*387f9dfdSAndroid Build Coastguard Worker 		env.interval = strtol(arg, NULL, 10);
94*387f9dfdSAndroid Build Coastguard Worker 		if (errno || env.interval <= 0) {
95*387f9dfdSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid interval: %s\n", arg);
96*387f9dfdSAndroid Build Coastguard Worker 			argp_usage(state);
97*387f9dfdSAndroid Build Coastguard Worker 		}
98*387f9dfdSAndroid Build Coastguard Worker 		break;
99*387f9dfdSAndroid Build Coastguard Worker 	case 'd':
100*387f9dfdSAndroid Build Coastguard Worker 		errno = 0;
101*387f9dfdSAndroid Build Coastguard Worker 		env.duration = strtol(arg, NULL, 10);
102*387f9dfdSAndroid Build Coastguard Worker 		if (errno || env.duration <= 0) {
103*387f9dfdSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid duration: %s\n", arg);
104*387f9dfdSAndroid Build Coastguard Worker 			argp_usage(state);
105*387f9dfdSAndroid Build Coastguard Worker 		}
106*387f9dfdSAndroid Build Coastguard Worker 		break;
107*387f9dfdSAndroid Build Coastguard Worker 	case 'T':
108*387f9dfdSAndroid Build Coastguard Worker 		env.timestamp = true;
109*387f9dfdSAndroid Build Coastguard Worker 		break;
110*387f9dfdSAndroid Build Coastguard Worker 	case 'm':
111*387f9dfdSAndroid Build Coastguard Worker 		env.milliseconds = true;
112*387f9dfdSAndroid Build Coastguard Worker 		break;
113*387f9dfdSAndroid Build Coastguard Worker 	case 'p':
114*387f9dfdSAndroid Build Coastguard Worker 		errno = 0;
115*387f9dfdSAndroid Build Coastguard Worker 		env.lport = strtoul(arg, NULL, 10);
116*387f9dfdSAndroid Build Coastguard Worker 		if (errno) {
117*387f9dfdSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid lport: %s\n", arg);
118*387f9dfdSAndroid Build Coastguard Worker 			argp_usage(state);
119*387f9dfdSAndroid Build Coastguard Worker 		}
120*387f9dfdSAndroid Build Coastguard Worker 		env.lport = htons(env.lport);
121*387f9dfdSAndroid Build Coastguard Worker 		break;
122*387f9dfdSAndroid Build Coastguard Worker 	case 'P':
123*387f9dfdSAndroid Build Coastguard Worker 		errno = 0;
124*387f9dfdSAndroid Build Coastguard Worker 		env.rport = strtoul(arg, NULL, 10);
125*387f9dfdSAndroid Build Coastguard Worker 		if (errno) {
126*387f9dfdSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid rport: %s\n", arg);
127*387f9dfdSAndroid Build Coastguard Worker 			argp_usage(state);
128*387f9dfdSAndroid Build Coastguard Worker 		}
129*387f9dfdSAndroid Build Coastguard Worker 		env.rport = htons(env.rport);
130*387f9dfdSAndroid Build Coastguard Worker 		break;
131*387f9dfdSAndroid Build Coastguard Worker 	case 'a':
132*387f9dfdSAndroid Build Coastguard Worker                 if (strchr(arg, ':')) {
133*387f9dfdSAndroid Build Coastguard Worker                         if (inet_pton(AF_INET6, arg, &addr_v6) < 1) {
134*387f9dfdSAndroid Build Coastguard Worker                                 fprintf(stderr, "invalid local IPv6 address: %s\n", arg);
135*387f9dfdSAndroid Build Coastguard Worker                                 argp_usage(state);
136*387f9dfdSAndroid Build Coastguard Worker                         }
137*387f9dfdSAndroid Build Coastguard Worker                         memcpy(env.laddr_v6, &addr_v6, sizeof(env.laddr_v6));
138*387f9dfdSAndroid Build Coastguard Worker                 } else {
139*387f9dfdSAndroid Build Coastguard Worker                         if (inet_pton(AF_INET, arg, &addr) < 0) {
140*387f9dfdSAndroid Build Coastguard Worker                                 fprintf(stderr, "invalid local address: %s\n", arg);
141*387f9dfdSAndroid Build Coastguard Worker                                 argp_usage(state);
142*387f9dfdSAndroid Build Coastguard Worker                         }
143*387f9dfdSAndroid Build Coastguard Worker                         env.laddr = addr.s_addr;
144*387f9dfdSAndroid Build Coastguard Worker                 }
145*387f9dfdSAndroid Build Coastguard Worker 		break;
146*387f9dfdSAndroid Build Coastguard Worker 	case 'A':
147*387f9dfdSAndroid Build Coastguard Worker                 if (strchr(arg, ':')) {
148*387f9dfdSAndroid Build Coastguard Worker                         if (inet_pton(AF_INET6, arg, &addr_v6) < 1) {
149*387f9dfdSAndroid Build Coastguard Worker                                 fprintf(stderr, "invalid remote address: %s\n", arg);
150*387f9dfdSAndroid Build Coastguard Worker                                 argp_usage(state);
151*387f9dfdSAndroid Build Coastguard Worker                         }
152*387f9dfdSAndroid Build Coastguard Worker                         memcpy(env.raddr_v6, &addr_v6, sizeof(env.raddr_v6));
153*387f9dfdSAndroid Build Coastguard Worker                 } else {
154*387f9dfdSAndroid Build Coastguard Worker                         if (inet_pton(AF_INET, arg, &addr) < 0) {
155*387f9dfdSAndroid Build Coastguard Worker                                 fprintf(stderr, "invalid remote address: %s\n", arg);
156*387f9dfdSAndroid Build Coastguard Worker                                 argp_usage(state);
157*387f9dfdSAndroid Build Coastguard Worker                         }
158*387f9dfdSAndroid Build Coastguard Worker                         env.raddr = addr.s_addr;
159*387f9dfdSAndroid Build Coastguard Worker                 }
160*387f9dfdSAndroid Build Coastguard Worker 		break;
161*387f9dfdSAndroid Build Coastguard Worker 	case 'b':
162*387f9dfdSAndroid Build Coastguard Worker 		env.laddr_hist = true;
163*387f9dfdSAndroid Build Coastguard Worker 		break;
164*387f9dfdSAndroid Build Coastguard Worker 	case 'B':
165*387f9dfdSAndroid Build Coastguard Worker 		env.raddr_hist = true;
166*387f9dfdSAndroid Build Coastguard Worker 		break;
167*387f9dfdSAndroid Build Coastguard Worker 	case 'e':
168*387f9dfdSAndroid Build Coastguard Worker 		env.extended = true;
169*387f9dfdSAndroid Build Coastguard Worker 		break;
170*387f9dfdSAndroid Build Coastguard Worker 	default:
171*387f9dfdSAndroid Build Coastguard Worker 		return ARGP_ERR_UNKNOWN;
172*387f9dfdSAndroid Build Coastguard Worker 	}
173*387f9dfdSAndroid Build Coastguard Worker 	return 0;
174*387f9dfdSAndroid Build Coastguard Worker }
175*387f9dfdSAndroid Build Coastguard Worker 
libbpf_print_fn(enum libbpf_print_level level,const char * format,va_list args)176*387f9dfdSAndroid Build Coastguard Worker static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
177*387f9dfdSAndroid Build Coastguard Worker {
178*387f9dfdSAndroid Build Coastguard Worker 	if (level == LIBBPF_DEBUG && !env.verbose)
179*387f9dfdSAndroid Build Coastguard Worker 		return 0;
180*387f9dfdSAndroid Build Coastguard Worker 	return vfprintf(stderr, format, args);
181*387f9dfdSAndroid Build Coastguard Worker }
182*387f9dfdSAndroid Build Coastguard Worker 
sig_handler(int sig)183*387f9dfdSAndroid Build Coastguard Worker static void sig_handler(int sig)
184*387f9dfdSAndroid Build Coastguard Worker {
185*387f9dfdSAndroid Build Coastguard Worker 	exiting = true;
186*387f9dfdSAndroid Build Coastguard Worker }
187*387f9dfdSAndroid Build Coastguard Worker 
print_map(struct bpf_map * map)188*387f9dfdSAndroid Build Coastguard Worker static int print_map(struct bpf_map *map)
189*387f9dfdSAndroid Build Coastguard Worker {
190*387f9dfdSAndroid Build Coastguard Worker 	const char *units = env.milliseconds ? "msecs" : "usecs";
191*387f9dfdSAndroid Build Coastguard Worker 	struct hist_key *lookup_key = NULL, next_key;
192*387f9dfdSAndroid Build Coastguard Worker 	int err, fd = bpf_map__fd(map);
193*387f9dfdSAndroid Build Coastguard Worker 	struct hist hist;
194*387f9dfdSAndroid Build Coastguard Worker 
195*387f9dfdSAndroid Build Coastguard Worker 	while (!bpf_map_get_next_key(fd, lookup_key, &next_key)) {
196*387f9dfdSAndroid Build Coastguard Worker 		err = bpf_map_lookup_elem(fd, &next_key, &hist);
197*387f9dfdSAndroid Build Coastguard Worker 		if (err < 0) {
198*387f9dfdSAndroid Build Coastguard Worker 			fprintf(stderr, "failed to lookup infos: %d\n", err);
199*387f9dfdSAndroid Build Coastguard Worker 			return -1;
200*387f9dfdSAndroid Build Coastguard Worker 		}
201*387f9dfdSAndroid Build Coastguard Worker 
202*387f9dfdSAndroid Build Coastguard Worker 
203*387f9dfdSAndroid Build Coastguard Worker 		if (env.laddr_hist)
204*387f9dfdSAndroid Build Coastguard Worker 			printf("Local Address = ");
205*387f9dfdSAndroid Build Coastguard Worker 		else if (env.raddr_hist)
206*387f9dfdSAndroid Build Coastguard Worker 			printf("Remote Address = ");
207*387f9dfdSAndroid Build Coastguard Worker 		else
208*387f9dfdSAndroid Build Coastguard Worker 			printf("All Addresses = ****** ");
209*387f9dfdSAndroid Build Coastguard Worker 
210*387f9dfdSAndroid Build Coastguard Worker 		if (env.laddr_hist || env.raddr_hist) {
211*387f9dfdSAndroid Build Coastguard Worker 			__u16 family = next_key.family;
212*387f9dfdSAndroid Build Coastguard Worker 			char str[INET6_ADDRSTRLEN];
213*387f9dfdSAndroid Build Coastguard Worker 
214*387f9dfdSAndroid Build Coastguard Worker 			if (!inet_ntop(family, next_key.addr, str, sizeof(str))) {
215*387f9dfdSAndroid Build Coastguard Worker 				perror("converting IP to string:");
216*387f9dfdSAndroid Build Coastguard Worker 				return -1;
217*387f9dfdSAndroid Build Coastguard Worker 			}
218*387f9dfdSAndroid Build Coastguard Worker 
219*387f9dfdSAndroid Build Coastguard Worker 			printf("%s ", str);
220*387f9dfdSAndroid Build Coastguard Worker 		}
221*387f9dfdSAndroid Build Coastguard Worker 
222*387f9dfdSAndroid Build Coastguard Worker 		if (env.extended)
223*387f9dfdSAndroid Build Coastguard Worker 			printf("[AVG %llu]", hist.latency / hist.cnt);
224*387f9dfdSAndroid Build Coastguard Worker 		printf("\n");
225*387f9dfdSAndroid Build Coastguard Worker 		print_log2_hist(hist.slots, MAX_SLOTS, units);
226*387f9dfdSAndroid Build Coastguard Worker 		lookup_key = &next_key;
227*387f9dfdSAndroid Build Coastguard Worker 	}
228*387f9dfdSAndroid Build Coastguard Worker 
229*387f9dfdSAndroid Build Coastguard Worker 	lookup_key = NULL;
230*387f9dfdSAndroid Build Coastguard Worker 	while (!bpf_map_get_next_key(fd, lookup_key, &next_key)) {
231*387f9dfdSAndroid Build Coastguard Worker 		err = bpf_map_delete_elem(fd, &next_key);
232*387f9dfdSAndroid Build Coastguard Worker 		if (err < 0) {
233*387f9dfdSAndroid Build Coastguard Worker 			fprintf(stderr, "failed to cleanup infos: %d\n", err);
234*387f9dfdSAndroid Build Coastguard Worker 			return -1;
235*387f9dfdSAndroid Build Coastguard Worker 		}
236*387f9dfdSAndroid Build Coastguard Worker 		lookup_key = &next_key;
237*387f9dfdSAndroid Build Coastguard Worker 	}
238*387f9dfdSAndroid Build Coastguard Worker 
239*387f9dfdSAndroid Build Coastguard Worker 	return 0;
240*387f9dfdSAndroid Build Coastguard Worker }
241*387f9dfdSAndroid Build Coastguard Worker 
main(int argc,char ** argv)242*387f9dfdSAndroid Build Coastguard Worker int main(int argc, char **argv)
243*387f9dfdSAndroid Build Coastguard Worker {
244*387f9dfdSAndroid Build Coastguard Worker 	static const struct argp argp = {
245*387f9dfdSAndroid Build Coastguard Worker 		.options = opts,
246*387f9dfdSAndroid Build Coastguard Worker 		.parser = parse_arg,
247*387f9dfdSAndroid Build Coastguard Worker 		.doc = argp_program_doc,
248*387f9dfdSAndroid Build Coastguard Worker 	};
249*387f9dfdSAndroid Build Coastguard Worker 	__u8 zero_addr_v6[IPV6_LEN] = {};
250*387f9dfdSAndroid Build Coastguard Worker 	struct tcprtt_bpf *obj;
251*387f9dfdSAndroid Build Coastguard Worker 	__u64 time_end = 0;
252*387f9dfdSAndroid Build Coastguard Worker 	struct tm *tm;
253*387f9dfdSAndroid Build Coastguard Worker 	char ts[32];
254*387f9dfdSAndroid Build Coastguard Worker 	time_t t;
255*387f9dfdSAndroid Build Coastguard Worker 	int err;
256*387f9dfdSAndroid Build Coastguard Worker 
257*387f9dfdSAndroid Build Coastguard Worker 	err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
258*387f9dfdSAndroid Build Coastguard Worker 	if (err)
259*387f9dfdSAndroid Build Coastguard Worker 		return err;
260*387f9dfdSAndroid Build Coastguard Worker 
261*387f9dfdSAndroid Build Coastguard Worker 	if ((env.laddr || env.raddr)
262*387f9dfdSAndroid Build Coastguard Worker 		&& (memcmp(env.laddr_v6, zero_addr_v6, sizeof(env.laddr_v6)) || memcmp(env.raddr_v6, zero_addr_v6, sizeof(env.raddr_v6)))) {
263*387f9dfdSAndroid Build Coastguard Worker 		fprintf(stderr, "It is not permitted to filter by both IPv4 and IPv6\n");
264*387f9dfdSAndroid Build Coastguard Worker 		return 1;
265*387f9dfdSAndroid Build Coastguard Worker 	}
266*387f9dfdSAndroid Build Coastguard Worker 
267*387f9dfdSAndroid Build Coastguard Worker 	libbpf_set_print(libbpf_print_fn);
268*387f9dfdSAndroid Build Coastguard Worker 
269*387f9dfdSAndroid Build Coastguard Worker 	obj = tcprtt_bpf__open();
270*387f9dfdSAndroid Build Coastguard Worker 	if (!obj) {
271*387f9dfdSAndroid Build Coastguard Worker 		fprintf(stderr, "failed to open BPF object\n");
272*387f9dfdSAndroid Build Coastguard Worker 		return 1;
273*387f9dfdSAndroid Build Coastguard Worker 	}
274*387f9dfdSAndroid Build Coastguard Worker 
275*387f9dfdSAndroid Build Coastguard Worker 	obj->rodata->targ_laddr_hist = env.laddr_hist;
276*387f9dfdSAndroid Build Coastguard Worker 	obj->rodata->targ_raddr_hist = env.raddr_hist;
277*387f9dfdSAndroid Build Coastguard Worker 	obj->rodata->targ_show_ext = env.extended;
278*387f9dfdSAndroid Build Coastguard Worker 	obj->rodata->targ_sport = env.lport;
279*387f9dfdSAndroid Build Coastguard Worker 	obj->rodata->targ_dport = env.rport;
280*387f9dfdSAndroid Build Coastguard Worker 	obj->rodata->targ_saddr = env.laddr;
281*387f9dfdSAndroid Build Coastguard Worker 	obj->rodata->targ_daddr = env.raddr;
282*387f9dfdSAndroid Build Coastguard Worker 	memcpy(obj->rodata->targ_saddr_v6, env.laddr_v6, sizeof(obj->rodata->targ_saddr_v6));
283*387f9dfdSAndroid Build Coastguard Worker 	memcpy(obj->rodata->targ_daddr_v6, env.raddr_v6, sizeof(obj->rodata->targ_daddr_v6));
284*387f9dfdSAndroid Build Coastguard Worker 	obj->rodata->targ_ms = env.milliseconds;
285*387f9dfdSAndroid Build Coastguard Worker 
286*387f9dfdSAndroid Build Coastguard Worker 	if (fentry_can_attach("tcp_rcv_established", NULL))
287*387f9dfdSAndroid Build Coastguard Worker 		bpf_program__set_autoload(obj->progs.tcp_rcv_kprobe, false);
288*387f9dfdSAndroid Build Coastguard Worker 	else
289*387f9dfdSAndroid Build Coastguard Worker 		bpf_program__set_autoload(obj->progs.tcp_rcv, false);
290*387f9dfdSAndroid Build Coastguard Worker 
291*387f9dfdSAndroid Build Coastguard Worker 	err = tcprtt_bpf__load(obj);
292*387f9dfdSAndroid Build Coastguard Worker 	if (err) {
293*387f9dfdSAndroid Build Coastguard Worker 		fprintf(stderr, "failed to load BPF object: %d\n", err);
294*387f9dfdSAndroid Build Coastguard Worker 		goto cleanup;
295*387f9dfdSAndroid Build Coastguard Worker 	}
296*387f9dfdSAndroid Build Coastguard Worker 
297*387f9dfdSAndroid Build Coastguard Worker 	err = tcprtt_bpf__attach(obj);
298*387f9dfdSAndroid Build Coastguard Worker 	if (err) {
299*387f9dfdSAndroid Build Coastguard Worker 		fprintf(stderr, "failed to attach BPF programs: %d\n", err);
300*387f9dfdSAndroid Build Coastguard Worker 		goto cleanup;
301*387f9dfdSAndroid Build Coastguard Worker 	}
302*387f9dfdSAndroid Build Coastguard Worker 
303*387f9dfdSAndroid Build Coastguard Worker 	signal(SIGINT, sig_handler);
304*387f9dfdSAndroid Build Coastguard Worker 
305*387f9dfdSAndroid Build Coastguard Worker 	printf("Tracing TCP RTT");
306*387f9dfdSAndroid Build Coastguard Worker 	if (env.duration)
307*387f9dfdSAndroid Build Coastguard Worker 		printf(" for %ld secs.\n", env.duration);
308*387f9dfdSAndroid Build Coastguard Worker 	else
309*387f9dfdSAndroid Build Coastguard Worker 		printf("... Hit Ctrl-C to end.\n");
310*387f9dfdSAndroid Build Coastguard Worker 
311*387f9dfdSAndroid Build Coastguard Worker 	/* setup duration */
312*387f9dfdSAndroid Build Coastguard Worker 	if (env.duration)
313*387f9dfdSAndroid Build Coastguard Worker 		time_end = get_ktime_ns() + env.duration * NSEC_PER_SEC;
314*387f9dfdSAndroid Build Coastguard Worker 
315*387f9dfdSAndroid Build Coastguard Worker 	/* main: poll */
316*387f9dfdSAndroid Build Coastguard Worker 	while (1) {
317*387f9dfdSAndroid Build Coastguard Worker 		sleep(env.interval);
318*387f9dfdSAndroid Build Coastguard Worker 		printf("\n");
319*387f9dfdSAndroid Build Coastguard Worker 
320*387f9dfdSAndroid Build Coastguard Worker 		if (env.timestamp) {
321*387f9dfdSAndroid Build Coastguard Worker 			time(&t);
322*387f9dfdSAndroid Build Coastguard Worker 			tm = localtime(&t);
323*387f9dfdSAndroid Build Coastguard Worker 			strftime(ts, sizeof(ts), "%H:%M:%S", tm);
324*387f9dfdSAndroid Build Coastguard Worker 			printf("%-8s\n", ts);
325*387f9dfdSAndroid Build Coastguard Worker 		}
326*387f9dfdSAndroid Build Coastguard Worker 
327*387f9dfdSAndroid Build Coastguard Worker 		err = print_map(obj->maps.hists);
328*387f9dfdSAndroid Build Coastguard Worker 		if (err)
329*387f9dfdSAndroid Build Coastguard Worker 			break;
330*387f9dfdSAndroid Build Coastguard Worker 
331*387f9dfdSAndroid Build Coastguard Worker 		if (env.duration && get_ktime_ns() > time_end)
332*387f9dfdSAndroid Build Coastguard Worker 			goto cleanup;
333*387f9dfdSAndroid Build Coastguard Worker 
334*387f9dfdSAndroid Build Coastguard Worker 		if (exiting)
335*387f9dfdSAndroid Build Coastguard Worker 			break;
336*387f9dfdSAndroid Build Coastguard Worker 	}
337*387f9dfdSAndroid Build Coastguard Worker 
338*387f9dfdSAndroid Build Coastguard Worker cleanup:
339*387f9dfdSAndroid Build Coastguard Worker 	tcprtt_bpf__destroy(obj);
340*387f9dfdSAndroid Build Coastguard Worker 	return err != 0;
341*387f9dfdSAndroid Build Coastguard Worker }
342