目标:编写一个不需要高权限的 eBPF 包过滤程序。
问题:据我了解,我必须使用attach_raw_socket
函数将过滤器附加到接口。此函数调用bpf_open_raw_sock
libbpf 函数,该函数打开需要高权限的 raw_socket ( https://github.com/iovisor/bcc/blob/10dae9eac33287c1df9e6645933b608c2d2c5640/src/cc/libbpf.c#L674-L678 )。
问题:有没有办法将 ebpf 过滤器附加到另一种套接字类型,例如 SOCK_DGRAM(可以使用 cBPF)?
#!/usr/bin/python
from bcc import BPF
import socket
import os
# backend part
# ebpf program written using restricted C
c_ebpf = """
#include <uapi/linux/if_ether.h>
#include <uapi/linux/ip.h>
#include <linux/in.h>
#include <linux/if_packet.h>
int icmp_filter(struct __sk_buff *skb){
int proto = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
if(proto == IPPROTO_ICMP && skb->pkt_type == PACKET_OUTGOING){
return -1;
} else { return 0; }
}
"""
# loader
bpf = BPF(text=c_ebpf)
ffilter = bpf.load_func("icmp_filter", BPF.SOCKET_FILTER)
BPF.attach_raw_socket(ffilter, "enp0s3")
# frontend part
socketfd = ffilter.sock
sockobj = socket.fromfd(socketfd, socket.AF_PACKET, socket.SOCK_RAW, socket.IPPROTO_IP)
sockobj.setblocking(True)
while 1:
pkt_str = os.read(socketfd, 2048)
pkt_bytearray = bytearray(pkt_str)
ip_protocol = pkt_bytearray[23]
print ("%s" % hex(ip_protocol))