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