1 #include <stdio.h>
2 #include <string.h>
3 #include <linux/bpf.h>
4 #include <unistd.h>
5 #include <asm/unistd.h>
6
sys_bpf(enum bpf_cmd cmd,union bpf_attr * attr,unsigned int size)7 static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size)
8 {
9 return syscall(__NR_bpf, cmd, attr, size);
10 }
11
ptr_to_u64(const void * ptr)12 static inline __u64 ptr_to_u64(const void *ptr)
13 {
14 return (__u64) (unsigned long) ptr;
15 }
16
parse(char * p)17 unsigned int parse(char *p) {
18 int k, i=0, b;
19 unsigned int ip=0, mk=0xffffffff;
20 for (k=0; k<4; k++) {
21 b=0;
22 if (p[i]<'0'||p[i]>'9') return 0;
23 while(p[i]>='0'&&p[i]<='9') {
24 b=b*10+p[i++]-'0';
25 if (b>256) return 0;
26 }
27 if (k<3&&p[i]!='.') return 0;
28 if (k==3&&p[i]!=0&&p[i]!='/') return 0;
29 ip = (ip<<8) | b;
30 if (k==3) break;
31 i++;
32 }
33 if (p[i]==0) mk=0xffffffff;
34 else if (p[i]=='/') {
35 i++; b=0;
36 while(p[i]>='0'&&p[i]<='9') {
37 b=b*10+p[i++]-'0';
38 if (b>32) return 0;
39 }
40 if (p[i]!=0||b>32||b<1) return 0;
41 b=32-b;
42 mk>>=b; mk<<=b;
43 } else return 0;
44 return ip&mk;
45 }
46
main(int argc,char * argv[])47 int main(int argc, char *argv[]) {
48 unsigned int ip, value;
49 union bpf_attr attr_pin, attr_elem;
50 int fd, rc;
51 memset(&attr_pin, 0, sizeof(attr_pin));
52 memset(&attr_elem, 0, sizeof(attr_elem));
53 attr_pin.pathname = ptr_to_u64("/sys/fs/bpf/rules");
54 fd = sys_bpf(BPF_OBJ_GET, &attr_pin, sizeof(attr_pin));
55 if (fd<0) {
56 printf("bpf map /sys/fs/bpf/rules not exist yet, need to start bpf prog first\n");
57 return 1;
58 }
59 attr_elem.map_fd = fd;
60 attr_elem.key = ptr_to_u64(&ip);
61 attr_elem.value = ptr_to_u64(&value);
62 if (argc != 3) {
63 printf("usage: %s [allow/block] [ipnetwork]\n", argv[0]);
64 return 1;
65 }
66 if (strcmp(argv[1], "allow")==0) {
67 ip = parse(argv[2]);
68 printf("allow ip %x\n", ip);
69 if (ip==0) {
70 printf("ip network %s not valid\n", argv[2]);
71 return 1;
72 }
73 value=0;
74 rc = sys_bpf(BPF_MAP_UPDATE_ELEM, &attr_elem, sizeof(attr_elem));
75 if (rc<0) {
76 printf("fail to register the firewall rule\n");
77 return 1;
78 }
79 } else if (strcmp(argv[1], "block")==0) {
80 ip = parse(argv[2]);
81 printf("block ip %x\n", ip);
82 if (ip==0) {
83 printf("ip network %s not valid\n", argv[2]);
84 return 1;
85 }
86 value=1;
87 rc = sys_bpf(BPF_MAP_UPDATE_ELEM, &attr_elem, sizeof(attr_elem));
88 if (rc<0) {
89 printf("fail to register the firewall rule\n");
90 return 1;
91 }
92 } else {
93 printf("usage: %s [allow/block] [ipnetwork]\n", argv[0]);
94 return 1;
95 }
96 }
97