xref: /linux-tools/ebpf/libbpf-bootstrap/conn.c (revision cf38d8f6bf0895297006d1c1b4976f0072bae4c9)
1*cf38d8f6SDavid Wang #include <signal.h>
2*cf38d8f6SDavid Wang #include <stdio.h>
3*cf38d8f6SDavid Wang #include <time.h>
4*cf38d8f6SDavid Wang #include <sys/resource.h>
5*cf38d8f6SDavid Wang #include <bpf/libbpf.h>
6*cf38d8f6SDavid Wang #include <time.h>
7*cf38d8f6SDavid Wang #include <sys/socket.h>
8*cf38d8f6SDavid Wang #include <netinet/in.h>
9*cf38d8f6SDavid Wang #include <netinet/ip.h>
10*cf38d8f6SDavid Wang 
11*cf38d8f6SDavid Wang #include "conn.h"
12*cf38d8f6SDavid Wang #include "conn.skel.h"
13*cf38d8f6SDavid Wang 
14*cf38d8f6SDavid Wang #include <map>
15*cf38d8f6SDavid Wang #include <algorithm>
16*cf38d8f6SDavid Wang #include <tuple>
17*cf38d8f6SDavid Wang #include <string>
18*cf38d8f6SDavid Wang #include <set>
19*cf38d8f6SDavid Wang using namespace std;
20*cf38d8f6SDavid Wang 
21*cf38d8f6SDavid Wang 
22*cf38d8f6SDavid Wang 
23*cf38d8f6SDavid Wang // cpp code, to compile run `CC=g++ make conn`
24*cf38d8f6SDavid Wang 
25*cf38d8f6SDavid Wang static struct ring_buffer *ring_buf = NULL;
26*cf38d8f6SDavid Wang static struct conn_bpf *skel = NULL;
27*cf38d8f6SDavid Wang static int exiting = 0;
int_exit(int sig)28*cf38d8f6SDavid Wang static void int_exit(int sig) {
29*cf38d8f6SDavid Wang     exiting = 1;
30*cf38d8f6SDavid Wang     if (ring_buf) {
31*cf38d8f6SDavid Wang         ring_buffer__free(ring_buf);
32*cf38d8f6SDavid Wang         ring_buf= NULL;
33*cf38d8f6SDavid Wang     }
34*cf38d8f6SDavid Wang     if (skel){
35*cf38d8f6SDavid Wang         conn_bpf__destroy(skel);
36*cf38d8f6SDavid Wang         skel = NULL;
37*cf38d8f6SDavid Wang     }
38*cf38d8f6SDavid Wang }
39*cf38d8f6SDavid Wang 
40*cf38d8f6SDavid Wang using xtt =  tuple<time_t, string, string>;
41*cf38d8f6SDavid Wang static map<int, xtt> pids;
42*cf38d8f6SDavid Wang char ob[256];
event_handler(void * _ctx,void * data,size_t size)43*cf38d8f6SDavid Wang static int event_handler(void *_ctx, void *data, size_t size) {
44*cf38d8f6SDavid Wang     if (size != sizeof(struct conn_event)){
45*cf38d8f6SDavid Wang         printf("receive unmatch size %d\n", (int)size);
46*cf38d8f6SDavid Wang         return 0;
47*cf38d8f6SDavid Wang     }
48*cf38d8f6SDavid Wang     struct conn_event* event = (struct conn_event*)data;
49*cf38d8f6SDavid Wang     struct sockaddr_in* addr = (struct sockaddr_in*)(&(event->addr));
50*cf38d8f6SDavid Wang     int port=0;
51*cf38d8f6SDavid Wang     if (addr->sin_family==AF_INET) {
52*cf38d8f6SDavid Wang         unsigned char *ip = (unsigned char*)(&(addr->sin_addr.s_addr));
53*cf38d8f6SDavid Wang         sprintf(ob, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
54*cf38d8f6SDavid Wang         port = ntohs(addr->sin_port);
55*cf38d8f6SDavid Wang     } else if (addr->sin_family==AF_INET6) {
56*cf38d8f6SDavid Wang         struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
57*cf38d8f6SDavid Wang         unsigned char *ip6 = addr6->sin6_addr.s6_addr;
58*cf38d8f6SDavid Wang         int k=0; for (k=0; k<16; k++) if (ip6[k]) break;
59*cf38d8f6SDavid Wang         int j=0;
60*cf38d8f6SDavid Wang         if (k==10) {
61*cf38d8f6SDavid Wang             ob[0]=':'; ob[1]=':'; j=2;
62*cf38d8f6SDavid Wang             for (; k<12; k++) {
63*cf38d8f6SDavid Wang                 if (ip6[k]!=0xff) break;
64*cf38d8f6SDavid Wang                 else { ob[j++]='F'; ob[j++]='F'; }
65*cf38d8f6SDavid Wang             }
66*cf38d8f6SDavid Wang             if (k==12) {
67*cf38d8f6SDavid Wang                 sprintf(ob+j, ":%d.%d.%d.%d", ip6[12], ip6[13], ip6[14], ip6[15]);
68*cf38d8f6SDavid Wang             } else {
69*cf38d8f6SDavid Wang                 while(k<16) {
70*cf38d8f6SDavid Wang                     if (k%4) ob[j++]=':';
71*cf38d8f6SDavid Wang                     j+=sprintf(ob+j, "%X", ip6[k]);
72*cf38d8f6SDavid Wang                     k++;
73*cf38d8f6SDavid Wang                 }
74*cf38d8f6SDavid Wang             }
75*cf38d8f6SDavid Wang         } else {
76*cf38d8f6SDavid Wang             if (k>4) {
77*cf38d8f6SDavid Wang                 ob[0]=':'; ob[1]=':'; j=2;
78*cf38d8f6SDavid Wang                 while(k<16) {
79*cf38d8f6SDavid Wang                     if (k%4) ob[j++]=':';
80*cf38d8f6SDavid Wang                     j+=sprintf(ob+j, "%X", ip6[k]);
81*cf38d8f6SDavid Wang                     k++;
82*cf38d8f6SDavid Wang                 }
83*cf38d8f6SDavid Wang             }
84*cf38d8f6SDavid Wang         }
85*cf38d8f6SDavid Wang         port = ntohs(addr6->sin6_port);
86*cf38d8f6SDavid Wang     } else return 0;
87*cf38d8f6SDavid Wang     int pid = event->pid;
88*cf38d8f6SDavid Wang     time_t ctime = time(NULL);
89*cf38d8f6SDavid Wang     char dir_in = 0;
90*cf38d8f6SDavid Wang     if (pid<0) { pid=-pid; dir_in=1; }
91*cf38d8f6SDavid Wang     if (pids.count(pid)==0 || ctime-get<0>(pids[pid]) > 1000) {
92*cf38d8f6SDavid Wang         char b[128];
93*cf38d8f6SDavid Wang         char comm[128];
94*cf38d8f6SDavid Wang         char host[128];
95*cf38d8f6SDavid Wang         sprintf(b, "/proc/%d/comm", pid);
96*cf38d8f6SDavid Wang         FILE* fp;
97*cf38d8f6SDavid Wang         size_t i=0;
98*cf38d8f6SDavid Wang         fp = fopen(b, "r"); if (fp) {
99*cf38d8f6SDavid Wang             comm[0]=0; fgets(comm, sizeof(comm), fp);
100*cf38d8f6SDavid Wang             while(i<sizeof(comm)&&comm[i]!=0&&comm[i]!='\n'&&comm[i]!='\r') i++;
101*cf38d8f6SDavid Wang             comm[i]=0;
102*cf38d8f6SDavid Wang             fclose(fp);
103*cf38d8f6SDavid Wang         }
104*cf38d8f6SDavid Wang         if (i<1) strcpy(comm, "unknown-command");
105*cf38d8f6SDavid Wang         sprintf(b, "/proc/%d/root/etc/hostname", pid);
106*cf38d8f6SDavid Wang         i=0; fp = fopen(b, "r"); if (fp) {
107*cf38d8f6SDavid Wang             host[0]=0; fgets(host, sizeof(host), fp);
108*cf38d8f6SDavid Wang             while(i<sizeof(host)&&host[i]!=0&&host[i]!='\n'&&host[i]!='\r') i++;
109*cf38d8f6SDavid Wang             host[i]=0;
110*cf38d8f6SDavid Wang             fclose(fp);
111*cf38d8f6SDavid Wang         }
112*cf38d8f6SDavid Wang         if (i<1) strcpy(host, "unknown-host");
113*cf38d8f6SDavid Wang         pids[pid] = make_tuple(ctime, string(comm), string(host));
114*cf38d8f6SDavid Wang     }
115*cf38d8f6SDavid Wang     if (dir_in) {
116*cf38d8f6SDavid Wang         // if (port)
117*cf38d8f6SDavid Wang             printf("[%s@%s] accept connection from <%s>\n", get<1>(pids[pid]).c_str(), get<2>(pids[pid]).c_str(), ob);
118*cf38d8f6SDavid Wang     } else {
119*cf38d8f6SDavid Wang         if (port)
120*cf38d8f6SDavid Wang             printf("[%s@%s] try to connect  <%s:%d>\n", get<1>(pids[pid]).c_str(), get<2>(pids[pid]).c_str(), ob, port);
121*cf38d8f6SDavid Wang         else
122*cf38d8f6SDavid Wang             printf("[%s@%s] try to reach  <%s>\n", get<1>(pids[pid]).c_str(), get<2>(pids[pid]).c_str(), ob);
123*cf38d8f6SDavid Wang     }
124*cf38d8f6SDavid Wang     return 0;
125*cf38d8f6SDavid Wang }
126*cf38d8f6SDavid Wang 
main(int argc,char * argv[])127*cf38d8f6SDavid Wang int main(int argc, char *argv[]) {
128*cf38d8f6SDavid Wang     int err;
129*cf38d8f6SDavid Wang 	signal(SIGINT, int_exit);
130*cf38d8f6SDavid Wang 	signal(SIGTERM, int_exit);
131*cf38d8f6SDavid Wang 	skel = conn_bpf__open();
132*cf38d8f6SDavid Wang 	if (!skel) {
133*cf38d8f6SDavid Wang 		fprintf(stderr, "Failed to open and load BPF skeleton\n");
134*cf38d8f6SDavid Wang 		return 1;
135*cf38d8f6SDavid Wang 	}
136*cf38d8f6SDavid Wang 	err = conn_bpf__load(skel);
137*cf38d8f6SDavid Wang 	if (err) {
138*cf38d8f6SDavid Wang 		fprintf(stderr, "Failed to load and verify BPF skeleton\n");
139*cf38d8f6SDavid Wang 		goto cleanup;
140*cf38d8f6SDavid Wang 	}
141*cf38d8f6SDavid Wang 	err = conn_bpf__attach(skel);
142*cf38d8f6SDavid Wang 	if (err) {
143*cf38d8f6SDavid Wang 		fprintf(stderr, "Failed to attach BPF skeleton\n");
144*cf38d8f6SDavid Wang 		goto cleanup;
145*cf38d8f6SDavid Wang 	}
146*cf38d8f6SDavid Wang     ring_buf = ring_buffer__new(bpf_map__fd(skel->maps.conns), event_handler, NULL, NULL);
147*cf38d8f6SDavid Wang     if (!ring_buf) {
148*cf38d8f6SDavid Wang         perror("Fail to alloc ring buf");
149*cf38d8f6SDavid Wang 		goto cleanup;
150*cf38d8f6SDavid Wang     }
151*cf38d8f6SDavid Wang 	while (!exiting) {
152*cf38d8f6SDavid Wang         if(ring_buffer__poll(ring_buf, -1) < 0) break;
153*cf38d8f6SDavid Wang     }
154*cf38d8f6SDavid Wang 
155*cf38d8f6SDavid Wang cleanup:
156*cf38d8f6SDavid Wang     int_exit(0);
157*cf38d8f6SDavid Wang     return 0;
158*cf38d8f6SDavid Wang }
159