xref: /linux-tools/ebpf/libbpf-bootstrap/commargv.c (revision a7aacf281090f97c77546704f587a77ff241bb2c)
1 #include <signal.h>
2 #include <stdio.h>
3 #include <time.h>
4 #include <sys/resource.h>
5 #include <bpf/libbpf.h>
6 #include <time.h>
7 
8 #include "commargv.h"
9 #include "commargv.skel.h"
10 
11 #include <map>
12 #include <algorithm>
13 #include <tuple>
14 #include <string>
15 #include <set>
16 using namespace std;
17 
18 
19 
20 // cpp code, to compile run `CC=g++ make commargv`
21 
22 static struct ring_buffer *ring_buf = NULL;
23 static struct commargv_bpf *skel = NULL;
24 static int exiting = 0;
25 static void int_exit(int sig) {
26     exiting = 1;
27     if (ring_buf) {
28         ring_buffer__free(ring_buf);
29         ring_buf= NULL;
30     }
31     if (skel){
32         commargv_bpf__destroy(skel);
33         skel = NULL;
34     }
35 }
36 
37 using xtt =  tuple<time_t, string, string>;
38 static map<int, xtt> pids;
39 static int event_handler(void *_ctx, void *data, size_t size) {
40     if (size != sizeof(struct comm_event)){
41         printf("receive unmatch size %d\n", (int)size);
42         return 0;
43     }
44     struct comm_event* event = (struct comm_event*)data;
45     // printf("receive event from %d[%s]\n", event->pid, event->comm);
46     if (event->n==0) return 0;
47     int pid = event->pid, i;
48     time_t ctime = time(NULL);
49     if (pids.count(pid)==0 || ctime-get<0>(pids[pid]) > 1000) {
50         char b[128];
51         char comm[128];
52         char host[128];
53         sprintf(b, "/proc/%d/comm", pid);
54         FILE* fp;
55         size_t i=0;
56         fp = fopen(b, "r"); if (fp) {
57             comm[0]=0; fgets(comm, sizeof(comm), fp);
58             while(i<sizeof(comm)&&comm[i]!=0&&comm[i]!='\n'&&comm[i]!='\r') i++;
59             comm[i]=0;
60             fclose(fp);
61         }
62         if (i<1) strcpy(comm, "unknown-command");
63         sprintf(b, "/proc/%d/root/etc/hostname", pid);
64         i=0; fp = fopen(b, "r"); if (fp) {
65             host[0]=0; fgets(host, sizeof(host), fp);
66             while(i<sizeof(host)&&host[i]!=0&&host[i]!='\n'&&host[i]!='\r') i++;
67             host[i]=0;
68             fclose(fp);
69         }
70         if (i<1) strcpy(host, "unknown-host");
71         pids[pid] = make_tuple(ctime, string(comm), string(host));
72     }
73     printf("[%s@%s]: ", get<1>(pids[pid]).c_str(), get<2>(pids[pid]).c_str());
74     for (i=0; i<event->n; i++) printf("%s ", event->argv[i]);
75     printf("\n");
76     return 0;
77 }
78 
79 int main(int argc, char *argv[]) {
80     int err;
81 	signal(SIGINT, int_exit);
82 	signal(SIGTERM, int_exit);
83 	skel = commargv_bpf__open();
84 	if (!skel) {
85 		fprintf(stderr, "Failed to open and load BPF skeleton\n");
86 		return 1;
87 	}
88 	err = commargv_bpf__load(skel);
89 	if (err) {
90 		fprintf(stderr, "Failed to load and verify BPF skeleton\n");
91 		goto cleanup;
92 	}
93 	err = commargv_bpf__attach(skel);
94 	if (err) {
95 		fprintf(stderr, "Failed to attach BPF skeleton\n");
96 		goto cleanup;
97 	}
98     ring_buf = ring_buffer__new(bpf_map__fd(skel->maps.comms), event_handler, NULL, NULL);
99     if (!ring_buf) {
100         perror("Fail to alloc ring buf");
101 		goto cleanup;
102     }
103 	while (!exiting) {
104         if(ring_buffer__poll(ring_buf, -1) < 0) break;
105     }
106 
107 cleanup:
108     int_exit(0);
109     return 0;
110 }
111