-
Notifications
You must be signed in to change notification settings - Fork 52
/
bpf.c
128 lines (102 loc) · 2.24 KB
/
bpf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/bpf.h>
#include <sys/socket.h>
#include <sys/syscall.h>
int bpf(int cmd, union bpf_attr *attrs)
{
return syscall(__NR_bpf, cmd, attrs, sizeof(*attrs));
}
int create_map(union bpf_attr* attrs)
{
int ret = -1;
ret = bpf(BPF_MAP_CREATE, attrs);
return ret;
}
int update_map_element(int map_fd, uint64_t key, void* value, uint64_t flags)
{
int ret = -1;
union bpf_attr attr =
{
.map_fd = map_fd,
.key = (uint64_t)&key,
.value = (uint64_t)value,
.flags = flags,
};
ret = bpf(BPF_MAP_UPDATE_ELEM, &attr);
return ret;
}
int lookup_map_element(int map_fd, uint64_t key, void* value)
{
int ret = -1;
union bpf_attr attr =
{
.map_fd = map_fd,
.key = (uint64_t)&key,
.value = (uint64_t)value,
};
ret = bpf(BPF_MAP_LOOKUP_ELEM, &attr);
return ret;
}
int obj_get_info_by_fd(union bpf_attr* attrs)
{
int ret = -1;
ret = bpf(BPF_OBJ_GET_INFO_BY_FD, attrs);
return ret;
}
int run_bpf_prog(struct bpf_insn* insn, uint32_t cnt, int* prog_fd_out)
{
int ret = -1;
int prog_fd = -1;
char verifier_log_buff[0x200000] = {0};
int socks[2] = {0};
union bpf_attr prog_attrs =
{
.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
.insn_cnt = cnt,
.insns = (uint64_t)insn,
.license = (uint64_t)"",
.log_level = 2,
.log_size = sizeof(verifier_log_buff),
.log_buf = (uint64_t)verifier_log_buff
};
if(NULL != prog_fd_out)
{
prog_fd = *prog_fd_out;
}
if(0 >= prog_fd)
{
prog_fd = bpf(BPF_PROG_LOAD, &prog_attrs);
}
if(0 > prog_fd)
{
puts(verifier_log_buff);
goto done;
}
if(0 != socketpair(AF_UNIX, SOCK_DGRAM, 0, socks))
{
goto done;
}
if(0 != setsockopt(socks[0], SOL_SOCKET, SO_ATTACH_BPF, &prog_fd, sizeof(int)))
{
goto done;
}
if(0x7 != write(socks[1], "ch0mpie", 0x7))
{
goto done;
}
if(NULL != prog_fd_out)
{
*prog_fd_out = prog_fd;
}
else
{
close(prog_fd);
}
ret = 0;
done:
close(socks[0]);
close(socks[1]);
return ret;
}