xref: /aosp_15_r20/external/bcc/introspection/bps.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker #include <time.h>
2*387f9dfdSAndroid Build Coastguard Worker #include <stdio.h>
3*387f9dfdSAndroid Build Coastguard Worker #include <errno.h>
4*387f9dfdSAndroid Build Coastguard Worker #include <string.h>
5*387f9dfdSAndroid Build Coastguard Worker #include <stdlib.h>
6*387f9dfdSAndroid Build Coastguard Worker #include <stdio.h>
7*387f9dfdSAndroid Build Coastguard Worker #include <stdint.h>
8*387f9dfdSAndroid Build Coastguard Worker #include <unistd.h>
9*387f9dfdSAndroid Build Coastguard Worker #include <ctype.h>
10*387f9dfdSAndroid Build Coastguard Worker #include <sysexits.h>
11*387f9dfdSAndroid Build Coastguard Worker 
12*387f9dfdSAndroid Build Coastguard Worker #include "libbpf.h"
13*387f9dfdSAndroid Build Coastguard Worker 
14*387f9dfdSAndroid Build Coastguard Worker // TODO: Remove this when CentOS 6 support is not needed anymore
15*387f9dfdSAndroid Build Coastguard Worker #ifndef CLOCK_BOOTTIME
16*387f9dfdSAndroid Build Coastguard Worker #define CLOCK_BOOTTIME 7
17*387f9dfdSAndroid Build Coastguard Worker #endif
18*387f9dfdSAndroid Build Coastguard Worker 
19*387f9dfdSAndroid Build Coastguard Worker static const char * const prog_type_strings[] = {
20*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_UNSPEC] = "unspec",
21*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SOCKET_FILTER] = "socket filter",
22*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_KPROBE] = "kprobe",
23*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SCHED_CLS] = "sched cls",
24*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SCHED_ACT] = "sched act",
25*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_TRACEPOINT] = "tracepoint",
26*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_XDP] = "xdp",
27*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_PERF_EVENT] = "perf event",
28*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_CGROUP_SKB] = "cgroup skb",
29*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_CGROUP_SOCK] = "cgroup sock",
30*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_LWT_IN] = "lwt in",
31*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_LWT_OUT] = "lwt out",
32*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_LWT_XMIT] = "lwt xmit",
33*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SOCK_OPS] = "sock ops",
34*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SK_SKB] = "sk skb",
35*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_CGROUP_DEVICE] = "cgroup_device",
36*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SK_MSG] = "sk_msg",
37*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_RAW_TRACEPOINT] = "raw_tracepoint",
38*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_CGROUP_SOCK_ADDR] = "cgroup_sock_addr",
39*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_LIRC_MODE2] = "lirc_mode2",
40*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SK_REUSEPORT] = "sk_reuseport",
41*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector",
42*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_CGROUP_SYSCTL] = "cgroup_sysctl",
43*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE] = "raw_tracepoint_writable",
44*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_CGROUP_SOCKOPT] = "cgroup_sockopt",
45*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_TRACING] = "tracing",
46*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_STRUCT_OPS] = "struct_ops",
47*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_EXT] = "ext",
48*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_LSM] = "lsm",
49*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SK_LOOKUP] = "sk_lookup",
50*387f9dfdSAndroid Build Coastguard Worker   [BPF_PROG_TYPE_SYSCALL] = "syscall",
51*387f9dfdSAndroid Build Coastguard Worker };
52*387f9dfdSAndroid Build Coastguard Worker 
53*387f9dfdSAndroid Build Coastguard Worker static const char * const map_type_strings[] = {
54*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_UNSPEC] = "unspec",
55*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_HASH] = "hash",
56*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_ARRAY] = "array",
57*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_PROG_ARRAY] = "prog array",
58*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_PERF_EVENT_ARRAY] = "perf-ev array",
59*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_PERCPU_HASH] = "percpu hash",
60*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_PERCPU_ARRAY] = "percpu array",
61*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_STACK_TRACE] = "stack trace",
62*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_CGROUP_ARRAY] = "cgroup array",
63*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_LRU_HASH] = "lru hash",
64*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_LRU_PERCPU_HASH] = "lru percpu hash",
65*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_LPM_TRIE] = "lpm trie",
66*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_ARRAY_OF_MAPS] = "array of maps",
67*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_HASH_OF_MAPS] = "hash of maps",
68*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_DEVMAP] = "devmap",
69*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_SOCKMAP] = "sockmap",
70*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_CPUMAP] = "cpumap",
71*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_SOCKHASH] = "sockhash",
72*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_CGROUP_STORAGE] = "cgroup_storage",
73*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_REUSEPORT_SOCKARRAY] = "reuseport_sockarray",
74*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE] = "precpu_cgroup_storage",
75*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_QUEUE] = "queue",
76*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_STACK] = "stack",
77*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_SK_STORAGE] = "sk_storage",
78*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_DEVMAP_HASH] = "devmap_hash",
79*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_STRUCT_OPS] = "struct_ops",
80*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_RINGBUF] = "ringbuf",
81*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_INODE_STORAGE] = "inode_storage",
82*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_TASK_STORAGE] = "task_storage",
83*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_BLOOM_FILTER] = "bloom_filter",
84*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_USER_RINGBUF] = "user_ringbuf",
85*387f9dfdSAndroid Build Coastguard Worker   [BPF_MAP_TYPE_CGRP_STORAGE] = "cgrp_storage",
86*387f9dfdSAndroid Build Coastguard Worker };
87*387f9dfdSAndroid Build Coastguard Worker 
88*387f9dfdSAndroid Build Coastguard Worker #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
89*387f9dfdSAndroid Build Coastguard Worker #define LAST_KNOWN_PROG_TYPE (ARRAY_SIZE(prog_type_strings) - 1)
90*387f9dfdSAndroid Build Coastguard Worker #define LAST_KNOWN_MAP_TYPE (ARRAY_SIZE(map_type_strings) - 1)
91*387f9dfdSAndroid Build Coastguard Worker #define min(x, y) ((x) < (y) ? (x) : (y))
92*387f9dfdSAndroid Build Coastguard Worker 
ptr_to_u64(const void * ptr)93*387f9dfdSAndroid Build Coastguard Worker static inline uint64_t ptr_to_u64(const void *ptr)
94*387f9dfdSAndroid Build Coastguard Worker {
95*387f9dfdSAndroid Build Coastguard Worker   return (uint64_t) (unsigned long) ptr;
96*387f9dfdSAndroid Build Coastguard Worker }
97*387f9dfdSAndroid Build Coastguard Worker 
u64_to_ptr(uint64_t ptr)98*387f9dfdSAndroid Build Coastguard Worker static inline void * u64_to_ptr(uint64_t ptr)
99*387f9dfdSAndroid Build Coastguard Worker {
100*387f9dfdSAndroid Build Coastguard Worker   return (void *) (unsigned long ) ptr;
101*387f9dfdSAndroid Build Coastguard Worker }
102*387f9dfdSAndroid Build Coastguard Worker 
handle_get_next_errno(int eno)103*387f9dfdSAndroid Build Coastguard Worker static int handle_get_next_errno(int eno)
104*387f9dfdSAndroid Build Coastguard Worker {
105*387f9dfdSAndroid Build Coastguard Worker   switch (eno) {
106*387f9dfdSAndroid Build Coastguard Worker     case ENOENT:
107*387f9dfdSAndroid Build Coastguard Worker       return 0;
108*387f9dfdSAndroid Build Coastguard Worker     case EINVAL:
109*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr, "Kernel does not support BPF introspection\n");
110*387f9dfdSAndroid Build Coastguard Worker       return EX_UNAVAILABLE;
111*387f9dfdSAndroid Build Coastguard Worker     case EPERM:
112*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr,
113*387f9dfdSAndroid Build Coastguard Worker               "Require CAP_SYS_ADMIN capability.  Please retry as root\n");
114*387f9dfdSAndroid Build Coastguard Worker       return EX_NOPERM;
115*387f9dfdSAndroid Build Coastguard Worker     default:
116*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr, "%s\n", strerror(errno));
117*387f9dfdSAndroid Build Coastguard Worker       return 1;
118*387f9dfdSAndroid Build Coastguard Worker   }
119*387f9dfdSAndroid Build Coastguard Worker }
120*387f9dfdSAndroid Build Coastguard Worker 
print_prog_hdr(void)121*387f9dfdSAndroid Build Coastguard Worker static void print_prog_hdr(void)
122*387f9dfdSAndroid Build Coastguard Worker {
123*387f9dfdSAndroid Build Coastguard Worker   printf("%9s %-15s %8s %6s %-12s %-15s\n",
124*387f9dfdSAndroid Build Coastguard Worker          "BID", "TYPE", "UID", "#MAPS", "LoadTime", "NAME");
125*387f9dfdSAndroid Build Coastguard Worker }
126*387f9dfdSAndroid Build Coastguard Worker 
print_prog_info(const struct bpf_prog_info * prog_info)127*387f9dfdSAndroid Build Coastguard Worker static void print_prog_info(const struct bpf_prog_info *prog_info)
128*387f9dfdSAndroid Build Coastguard Worker {
129*387f9dfdSAndroid Build Coastguard Worker   struct timespec real_time_ts, boot_time_ts;
130*387f9dfdSAndroid Build Coastguard Worker   time_t wallclock_load_time = 0;
131*387f9dfdSAndroid Build Coastguard Worker   char unknown_prog_type[16];
132*387f9dfdSAndroid Build Coastguard Worker   const char *prog_type;
133*387f9dfdSAndroid Build Coastguard Worker   char load_time[16];
134*387f9dfdSAndroid Build Coastguard Worker   struct tm load_tm;
135*387f9dfdSAndroid Build Coastguard Worker 
136*387f9dfdSAndroid Build Coastguard Worker   if (prog_info->type > LAST_KNOWN_PROG_TYPE) {
137*387f9dfdSAndroid Build Coastguard Worker     snprintf(unknown_prog_type, sizeof(unknown_prog_type), "<%u>",
138*387f9dfdSAndroid Build Coastguard Worker              prog_info->type);
139*387f9dfdSAndroid Build Coastguard Worker     unknown_prog_type[sizeof(unknown_prog_type) - 1] = '\0';
140*387f9dfdSAndroid Build Coastguard Worker     prog_type = unknown_prog_type;
141*387f9dfdSAndroid Build Coastguard Worker   } else {
142*387f9dfdSAndroid Build Coastguard Worker     prog_type = prog_type_strings[prog_info->type];
143*387f9dfdSAndroid Build Coastguard Worker   }
144*387f9dfdSAndroid Build Coastguard Worker 
145*387f9dfdSAndroid Build Coastguard Worker   if (!clock_gettime(CLOCK_REALTIME, &real_time_ts) &&
146*387f9dfdSAndroid Build Coastguard Worker       !clock_gettime(CLOCK_BOOTTIME, &boot_time_ts) &&
147*387f9dfdSAndroid Build Coastguard Worker       real_time_ts.tv_sec >= boot_time_ts.tv_sec)
148*387f9dfdSAndroid Build Coastguard Worker     wallclock_load_time =
149*387f9dfdSAndroid Build Coastguard Worker       (real_time_ts.tv_sec - boot_time_ts.tv_sec) +
150*387f9dfdSAndroid Build Coastguard Worker       prog_info->load_time / 1000000000;
151*387f9dfdSAndroid Build Coastguard Worker 
152*387f9dfdSAndroid Build Coastguard Worker   if (wallclock_load_time && localtime_r(&wallclock_load_time, &load_tm))
153*387f9dfdSAndroid Build Coastguard Worker     strftime(load_time, sizeof(load_time), "%b%d/%H:%M", &load_tm);
154*387f9dfdSAndroid Build Coastguard Worker   else
155*387f9dfdSAndroid Build Coastguard Worker     snprintf(load_time, sizeof(load_time), "<%llu>",
156*387f9dfdSAndroid Build Coastguard Worker              prog_info->load_time / 1000000000);
157*387f9dfdSAndroid Build Coastguard Worker   load_time[sizeof(load_time) - 1] = '\0';
158*387f9dfdSAndroid Build Coastguard Worker 
159*387f9dfdSAndroid Build Coastguard Worker   if (prog_info->jited_prog_len)
160*387f9dfdSAndroid Build Coastguard Worker     printf("%9u %-15s %8u %6u %-12s %-15s\n",
161*387f9dfdSAndroid Build Coastguard Worker            prog_info->id, prog_type, prog_info->created_by_uid,
162*387f9dfdSAndroid Build Coastguard Worker            prog_info->nr_map_ids, load_time, prog_info->name);
163*387f9dfdSAndroid Build Coastguard Worker   else
164*387f9dfdSAndroid Build Coastguard Worker     printf("%8u- %-15s %8u %6u %-12s %-15s\n",
165*387f9dfdSAndroid Build Coastguard Worker            prog_info->id, prog_type, prog_info->created_by_uid,
166*387f9dfdSAndroid Build Coastguard Worker            prog_info->nr_map_ids, load_time, prog_info->name);
167*387f9dfdSAndroid Build Coastguard Worker }
168*387f9dfdSAndroid Build Coastguard Worker 
print_map_hdr(void)169*387f9dfdSAndroid Build Coastguard Worker static void print_map_hdr(void)
170*387f9dfdSAndroid Build Coastguard Worker {
171*387f9dfdSAndroid Build Coastguard Worker   printf("%8s %-15s %-10s %8s %8s %8s %-15s\n",
172*387f9dfdSAndroid Build Coastguard Worker          "MID", "TYPE", "FLAGS", "KeySz", "ValueSz", "MaxEnts",
173*387f9dfdSAndroid Build Coastguard Worker          "NAME");
174*387f9dfdSAndroid Build Coastguard Worker }
175*387f9dfdSAndroid Build Coastguard Worker 
print_map_info(const struct bpf_map_info * map_info)176*387f9dfdSAndroid Build Coastguard Worker static void print_map_info(const struct bpf_map_info *map_info)
177*387f9dfdSAndroid Build Coastguard Worker {
178*387f9dfdSAndroid Build Coastguard Worker   char unknown_map_type[16];
179*387f9dfdSAndroid Build Coastguard Worker   const char *map_type;
180*387f9dfdSAndroid Build Coastguard Worker 
181*387f9dfdSAndroid Build Coastguard Worker   if (map_info->type > LAST_KNOWN_MAP_TYPE) {
182*387f9dfdSAndroid Build Coastguard Worker     snprintf(unknown_map_type, sizeof(unknown_map_type),
183*387f9dfdSAndroid Build Coastguard Worker              "<%u>", map_info->type);
184*387f9dfdSAndroid Build Coastguard Worker     unknown_map_type[sizeof(unknown_map_type) - 1] = '\0';
185*387f9dfdSAndroid Build Coastguard Worker     map_type = unknown_map_type;
186*387f9dfdSAndroid Build Coastguard Worker   } else {
187*387f9dfdSAndroid Build Coastguard Worker     map_type = map_type_strings[map_info->type];
188*387f9dfdSAndroid Build Coastguard Worker   }
189*387f9dfdSAndroid Build Coastguard Worker 
190*387f9dfdSAndroid Build Coastguard Worker   printf("%8u %-15s 0x%-8x %8u %8u %8u %-15s\n",
191*387f9dfdSAndroid Build Coastguard Worker          map_info->id, map_type, map_info->map_flags, map_info->key_size,
192*387f9dfdSAndroid Build Coastguard Worker          map_info->value_size, map_info->max_entries,
193*387f9dfdSAndroid Build Coastguard Worker          map_info->name);
194*387f9dfdSAndroid Build Coastguard Worker }
195*387f9dfdSAndroid Build Coastguard Worker 
print_one_prog(uint32_t prog_id)196*387f9dfdSAndroid Build Coastguard Worker static int print_one_prog(uint32_t prog_id)
197*387f9dfdSAndroid Build Coastguard Worker {
198*387f9dfdSAndroid Build Coastguard Worker   const uint32_t usual_nr_map_ids = 64;
199*387f9dfdSAndroid Build Coastguard Worker   uint32_t nr_map_ids = usual_nr_map_ids;
200*387f9dfdSAndroid Build Coastguard Worker   struct bpf_prog_info prog_info;
201*387f9dfdSAndroid Build Coastguard Worker   uint32_t *map_ids =  NULL;
202*387f9dfdSAndroid Build Coastguard Worker   uint32_t info_len;
203*387f9dfdSAndroid Build Coastguard Worker   int ret = 0;
204*387f9dfdSAndroid Build Coastguard Worker   int prog_fd;
205*387f9dfdSAndroid Build Coastguard Worker   uint32_t i;
206*387f9dfdSAndroid Build Coastguard Worker 
207*387f9dfdSAndroid Build Coastguard Worker   prog_fd = bpf_prog_get_fd_by_id(prog_id);
208*387f9dfdSAndroid Build Coastguard Worker   if (prog_fd == -1) {
209*387f9dfdSAndroid Build Coastguard Worker     if (errno == ENOENT) {
210*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr, "BID:%u not found\n", prog_id);
211*387f9dfdSAndroid Build Coastguard Worker       return EX_DATAERR;
212*387f9dfdSAndroid Build Coastguard Worker     } else {
213*387f9dfdSAndroid Build Coastguard Worker       return handle_get_next_errno(errno);
214*387f9dfdSAndroid Build Coastguard Worker     }
215*387f9dfdSAndroid Build Coastguard Worker   }
216*387f9dfdSAndroid Build Coastguard Worker 
217*387f9dfdSAndroid Build Coastguard Worker   /* Retry at most one time for larger map_ids array */
218*387f9dfdSAndroid Build Coastguard Worker   for (i = 0; i < 2; i++) {
219*387f9dfdSAndroid Build Coastguard Worker     bzero(&prog_info, sizeof(prog_info));
220*387f9dfdSAndroid Build Coastguard Worker     prog_info.map_ids = ptr_to_u64(realloc(map_ids,
221*387f9dfdSAndroid Build Coastguard Worker                                            nr_map_ids * sizeof(*map_ids)));
222*387f9dfdSAndroid Build Coastguard Worker     if (!prog_info.map_ids) {
223*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr,
224*387f9dfdSAndroid Build Coastguard Worker               "Cannot allocate memory for %u map_ids for BID:%u\n",
225*387f9dfdSAndroid Build Coastguard Worker               nr_map_ids, prog_id);
226*387f9dfdSAndroid Build Coastguard Worker       close(prog_fd);
227*387f9dfdSAndroid Build Coastguard Worker       free(map_ids);
228*387f9dfdSAndroid Build Coastguard Worker       return 1;
229*387f9dfdSAndroid Build Coastguard Worker     }
230*387f9dfdSAndroid Build Coastguard Worker 
231*387f9dfdSAndroid Build Coastguard Worker     map_ids = u64_to_ptr(prog_info.map_ids);
232*387f9dfdSAndroid Build Coastguard Worker     prog_info.nr_map_ids = nr_map_ids;
233*387f9dfdSAndroid Build Coastguard Worker     info_len = sizeof(prog_info);
234*387f9dfdSAndroid Build Coastguard Worker     ret = bpf_obj_get_info(prog_fd, &prog_info, &info_len);
235*387f9dfdSAndroid Build Coastguard Worker     if (ret) {
236*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr, "Cannot get info for BID:%u. %s(%d)\n",
237*387f9dfdSAndroid Build Coastguard Worker               prog_id, strerror(errno), errno);
238*387f9dfdSAndroid Build Coastguard Worker       close(prog_fd);
239*387f9dfdSAndroid Build Coastguard Worker       free(map_ids);
240*387f9dfdSAndroid Build Coastguard Worker       return ret;
241*387f9dfdSAndroid Build Coastguard Worker     }
242*387f9dfdSAndroid Build Coastguard Worker 
243*387f9dfdSAndroid Build Coastguard Worker     if (prog_info.nr_map_ids <= nr_map_ids)
244*387f9dfdSAndroid Build Coastguard Worker       break;
245*387f9dfdSAndroid Build Coastguard Worker 
246*387f9dfdSAndroid Build Coastguard Worker     nr_map_ids = prog_info.nr_map_ids;
247*387f9dfdSAndroid Build Coastguard Worker   }
248*387f9dfdSAndroid Build Coastguard Worker   close(prog_fd);
249*387f9dfdSAndroid Build Coastguard Worker 
250*387f9dfdSAndroid Build Coastguard Worker   print_prog_hdr();
251*387f9dfdSAndroid Build Coastguard Worker   print_prog_info(&prog_info);
252*387f9dfdSAndroid Build Coastguard Worker   printf("\n");
253*387f9dfdSAndroid Build Coastguard Worker 
254*387f9dfdSAndroid Build Coastguard Worker   /* Print all map_info used by the prog */
255*387f9dfdSAndroid Build Coastguard Worker   print_map_hdr();
256*387f9dfdSAndroid Build Coastguard Worker   nr_map_ids = min(prog_info.nr_map_ids, nr_map_ids);
257*387f9dfdSAndroid Build Coastguard Worker   for (i = 0; i < nr_map_ids; i++) {
258*387f9dfdSAndroid Build Coastguard Worker     struct bpf_map_info map_info = {};
259*387f9dfdSAndroid Build Coastguard Worker     info_len = sizeof(map_info);
260*387f9dfdSAndroid Build Coastguard Worker     int map_fd;
261*387f9dfdSAndroid Build Coastguard Worker 
262*387f9dfdSAndroid Build Coastguard Worker     map_fd = bpf_map_get_fd_by_id(map_ids[i]);
263*387f9dfdSAndroid Build Coastguard Worker     if (map_fd == -1) {
264*387f9dfdSAndroid Build Coastguard Worker       if (errno == -ENOENT)
265*387f9dfdSAndroid Build Coastguard Worker         continue;
266*387f9dfdSAndroid Build Coastguard Worker 
267*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr,
268*387f9dfdSAndroid Build Coastguard Worker               "Cannot get fd for map:%u. %s(%d)\n",
269*387f9dfdSAndroid Build Coastguard Worker               map_ids[i], strerror(errno), errno);
270*387f9dfdSAndroid Build Coastguard Worker       ret = map_fd;
271*387f9dfdSAndroid Build Coastguard Worker       break;
272*387f9dfdSAndroid Build Coastguard Worker     }
273*387f9dfdSAndroid Build Coastguard Worker 
274*387f9dfdSAndroid Build Coastguard Worker     ret = bpf_obj_get_info(map_fd, &map_info, &info_len);
275*387f9dfdSAndroid Build Coastguard Worker     close(map_fd);
276*387f9dfdSAndroid Build Coastguard Worker     if (ret) {
277*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr, "Cannot get info for map:%u. %s(%d)\n",
278*387f9dfdSAndroid Build Coastguard Worker               map_ids[i], strerror(errno), errno);
279*387f9dfdSAndroid Build Coastguard Worker       break;
280*387f9dfdSAndroid Build Coastguard Worker     }
281*387f9dfdSAndroid Build Coastguard Worker 
282*387f9dfdSAndroid Build Coastguard Worker     print_map_info(&map_info);
283*387f9dfdSAndroid Build Coastguard Worker   }
284*387f9dfdSAndroid Build Coastguard Worker 
285*387f9dfdSAndroid Build Coastguard Worker   free(map_ids);
286*387f9dfdSAndroid Build Coastguard Worker   return ret;
287*387f9dfdSAndroid Build Coastguard Worker }
288*387f9dfdSAndroid Build Coastguard Worker 
print_all_progs(void)289*387f9dfdSAndroid Build Coastguard Worker int print_all_progs(void)
290*387f9dfdSAndroid Build Coastguard Worker {
291*387f9dfdSAndroid Build Coastguard Worker   uint32_t next_id = 0;
292*387f9dfdSAndroid Build Coastguard Worker 
293*387f9dfdSAndroid Build Coastguard Worker   print_prog_hdr();
294*387f9dfdSAndroid Build Coastguard Worker 
295*387f9dfdSAndroid Build Coastguard Worker   while (!bpf_prog_get_next_id(next_id, &next_id)) {
296*387f9dfdSAndroid Build Coastguard Worker     struct bpf_prog_info prog_info = {};
297*387f9dfdSAndroid Build Coastguard Worker     uint32_t prog_info_len = sizeof(prog_info);
298*387f9dfdSAndroid Build Coastguard Worker     int prog_fd;
299*387f9dfdSAndroid Build Coastguard Worker     int ret;
300*387f9dfdSAndroid Build Coastguard Worker 
301*387f9dfdSAndroid Build Coastguard Worker     prog_fd = bpf_prog_get_fd_by_id(next_id);
302*387f9dfdSAndroid Build Coastguard Worker     if (prog_fd < 0) {
303*387f9dfdSAndroid Build Coastguard Worker       if (errno == ENOENT)
304*387f9dfdSAndroid Build Coastguard Worker         continue;
305*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr,
306*387f9dfdSAndroid Build Coastguard Worker               "Cannot get fd for BID:%u. %s(%d)\n",
307*387f9dfdSAndroid Build Coastguard Worker               next_id, strerror(errno), errno);
308*387f9dfdSAndroid Build Coastguard Worker       return 1;
309*387f9dfdSAndroid Build Coastguard Worker     }
310*387f9dfdSAndroid Build Coastguard Worker 
311*387f9dfdSAndroid Build Coastguard Worker     ret = bpf_obj_get_info(prog_fd, &prog_info, &prog_info_len);
312*387f9dfdSAndroid Build Coastguard Worker     close(prog_fd);
313*387f9dfdSAndroid Build Coastguard Worker     if (ret) {
314*387f9dfdSAndroid Build Coastguard Worker       fprintf(stderr,
315*387f9dfdSAndroid Build Coastguard Worker               "Cannot get bpf_prog_info for BID:%u. %s(%d)\n",
316*387f9dfdSAndroid Build Coastguard Worker               next_id, strerror(errno), errno);
317*387f9dfdSAndroid Build Coastguard Worker       return ret;
318*387f9dfdSAndroid Build Coastguard Worker     }
319*387f9dfdSAndroid Build Coastguard Worker 
320*387f9dfdSAndroid Build Coastguard Worker     print_prog_info(&prog_info);
321*387f9dfdSAndroid Build Coastguard Worker   }
322*387f9dfdSAndroid Build Coastguard Worker 
323*387f9dfdSAndroid Build Coastguard Worker   return handle_get_next_errno(errno);
324*387f9dfdSAndroid Build Coastguard Worker }
325*387f9dfdSAndroid Build Coastguard Worker 
usage(void)326*387f9dfdSAndroid Build Coastguard Worker void usage(void)
327*387f9dfdSAndroid Build Coastguard Worker {
328*387f9dfdSAndroid Build Coastguard Worker   printf("BPF Program Snapshot (bps):\n"
329*387f9dfdSAndroid Build Coastguard Worker          "List of all BPF programs loaded into the system.\n\n");
330*387f9dfdSAndroid Build Coastguard Worker   printf("Usage: bps [bpf-prog-id]\n");
331*387f9dfdSAndroid Build Coastguard Worker   printf("    [bpf-prog-id] If specified, it shows the details info of the bpf-prog\n");
332*387f9dfdSAndroid Build Coastguard Worker   printf("\n");
333*387f9dfdSAndroid Build Coastguard Worker }
334*387f9dfdSAndroid Build Coastguard Worker 
main(int argc,char ** argv)335*387f9dfdSAndroid Build Coastguard Worker int main(int argc, char **argv)
336*387f9dfdSAndroid Build Coastguard Worker {
337*387f9dfdSAndroid Build Coastguard Worker   if (argc > 1) {
338*387f9dfdSAndroid Build Coastguard Worker     if (!isdigit(*argv[1])) {
339*387f9dfdSAndroid Build Coastguard Worker       usage();
340*387f9dfdSAndroid Build Coastguard Worker       return EX_USAGE;
341*387f9dfdSAndroid Build Coastguard Worker     }
342*387f9dfdSAndroid Build Coastguard Worker     return print_one_prog((uint32_t)atoi(argv[1]));
343*387f9dfdSAndroid Build Coastguard Worker   }
344*387f9dfdSAndroid Build Coastguard Worker 
345*387f9dfdSAndroid Build Coastguard Worker   return print_all_progs();
346*387f9dfdSAndroid Build Coastguard Worker }
347