RAW socket을 이용하여 패킷을 수신하고자 할때 내가 원하는 패킷을 걸러내기 위해서는 많은 작업과 더불어 많은 성능손실을 감수해야 한다.
커널레벨에서 내가 원하는 패킷만 응용프로그램으로 전달하므로써 이러한 성능손실을 개선할수 있다.

ip_rcv 함수에 대한 kprobe를 설정하여 네트워크 패킷이 수신될 때마다 정보를 캡처하는 예제



struct data_t {
    u32 pid;
    u64 ts;
    u64 len;
    char comm[TASK_COMM_LEN];
    u32 saddr;
    u32 daddr;
};

BPF_PERF_OUTPUT(events);

int trace_ip_rcv(struct pt_regs *ctx, struct sk_buff *skb) {
    struct data_t data = {};
    u64 ts = bpf_ktime_get_ns();

    data.pid = bpf_get_current_pid_tgid() >> 32;
    data.ts = ts;
    data.len = skb->len;
    bpf_get_current_comm(&data.comm, sizeof(data.comm));

    struct iphdr *ip = (struct iphdr *)(skb->head + skb->network_header);
    data.saddr = ip->saddr;
    data.daddr = ip->daddr;

    events.perf_submit(ctx, &data, sizeof(data));
    return 0;
}

출력

PID: 0, Time: 12569578812226, Length: 46, Command: swapper/1, SADDR: 192.168.124.1, DADDR: 192.168.124.141
PID: 0, Time: 12569624698373, Length: 46, Command: swapper/1, SADDR: 192.168.124.1, DADDR: 192.168.124.141
PID: 0, Time: 12570633291013, Length: 46, Command: swapper/1, SADDR: 192.168.124.1, DADDR: 192.168.124.141
PID: 0, Time: 12571647296456, Length: 46, Command: swapper/1, SADDR: 192.168.124.1, DADDR: 192.168.124.141
PID: 23, Time: 12572648495978, Length: 46, Command: ksoftirqd/1, SADDR: 192.168.124.1, DADDR: 192.168.124.141
PID: 1131, Time: 12573655228828, Length: 46, Command: gnome-shell, SADDR: 192.168.124.1, DADDR: 192.168.124.141
PID: 0, Time: 12574658197408, Length: 46, Command: swapper/1, SADDR: 192.168.124.1, DADDR: 192.168.124.141
PID: 0, Time: 12575669368723, Length: 46, Command: swapper/1, SADDR: 192.168.124.1, DADDR: 192.168.124.141