1 #include <stdio.h> 2 #include <string.h> 3 #include <linux/bpf.h> 4 #include <unistd.h> 5 #include <asm/unistd.h> 6 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 12 static inline __u64 ptr_to_u64(const void *ptr) 13 { 14 return (__u64) (unsigned long) ptr; 15 } 16 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 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