Фильтр пакетов eBPF не дает мне правильных данных
Итак, я пытался посмотреть, могу ли я подключить фильтр пакетов eBPF к сетевому интерфейсу, enp32s0np1. Я пытаюсь перехватить все IP-адреса входящих отправителей. Однако выполнение приведенного ниже кода вызывает у меня странную реакцию. Вместо того, чтобы видеть IP-адрес отправителя, я вижу заполненные случайные числа.
Вот код:
from bcc import BPF
# Network interface to be monoitored
INTERFACE = "enp32s0np1"
bpf_text = """
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <net/sock.h>
#include <bcc/proto.h>
#include <uapi/linux/ptrace.h>
int skb_matching(struct __sk_buff *skb) {
u8 *cursor = 0;
u64 saddr =0;
void *data_end = (void*)(long)skb->data_end;
void *data = (void*)(long)skb->data;
struct ethhdr *eth = data;
u32 nh_off = 0;
nh_off = sizeof(*eth);
/* // Code here has been blocked because this part keeps giving me errors as well..
if (data + nh_off > data_end ) {
bpf_trace_printk("error");
}
*/
//bpf_trace_printk("%p", data);
struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
struct ip_t *ip = cursor_advance(cursor,sizeof(*ip));
saddr = ip -> dst;
bpf_trace_printk("sss = %d", saddr);
bpf_trace_printk("Incoming packet!\\n");
return -1;
}
"""
from ctypes import *
import sys
import socket
import os
import struct
bpf = BPF(text=bpf_text)
function_skb_matching = bpf.load_func("skb_matching", BPF.SOCKET_FILTER)
BPF.attach_raw_socket(function_skb_matching, INTERFACE)
print("=========================packet monitor=============================\n")
bpf.trace_print()
и вот результат:
handler27-3403 [010] ..s1 135652.183626: 0: sss = -1062731519 handler27-3403 [010] ..s1 135652.183642: 0: Incoming packet!!
handler27-3403 [010] ..s1 135652.183691: 0: sss = -1062731518 handler27-3403 [010] ..s1 135652.183695: 0: Incoming packet!!
<idle>-0 [010] ..s. 135653.184712: 0: sss = -1062731519 <idle>-0 [010] ..s. 135653.184728: 0: Incoming packet!!
<idle>-0 [010] ..s. 135653.184759: 0: sss = -1062731518 <idle>-0 [010] ..s. 135653.184760: 0: Incoming packet!!
<idle>-0 [010] ..s. 135654.205715: 0: sss = -1062731519 <idle>-0 [010] ..s. 135654.205734: 0: Incoming packet!!
<idle>-0 [010] ..s. 135654.205765: 0: sss = -1062731518 <idle>-0 [010] ..s. 135654.205766: 0: Incoming packet!!
<idle>-0 [010] ..s. 135655.229752: 0: sss = -1062731519 <idle>-0 [010] ..s. 135655.229771: 0: Incoming packet!!
<idle>-0 [010] ..s. 135655.229802: 0: sss = -1062731518 <idle>-0 [010] ..s. 135655.229802: 0: Incoming packet!!
<idle>-0 [010] ..s. 135656.253777: 0: sss = -1062731519 <idle>-0 [010] ..s. 135656.253796: 0: Incoming packet!!
<idle>-0 [010] ..s. 135656.253827: 0: sss = -1062731518 <idle>-0 [010] ..s. 135656.253828: 0: Incoming packet!!
<idle>-0 [010] ..s. 135657.194068: 0: sss = 16842752 <idle>-0 [010] ..s. 135657.194084: 0: Incoming packet!!
handler27-3403 [010] ..s1 135657.195105: 0: sss = 16908309 handler27-3403 [010] ..s1 135657.195111: 0: Incoming packet!!
<idle>-0 [010] ..s. 135657.213711: 0: sss = 16908288 <idle>-0 [010] ..s. 135657.213727: 0: Incoming packet!!
<idle>-0 [010] ..s. 135657.213741: 0: sss = 16842773 <idle>-0 [010] ..s. 135657.213742: 0: Incoming packet!!
<idle>-0 [010] ..s. 135657.277815: 0: sss = -1062731519 <idle>-0 [010] ..s. 135657.277832: 0: Incoming packet!!
<idle>-0 [010] ..s. 135657.277860: 0: sss = -1062731518 <idle>-0 [010] ..s. 135657.277861: 0: Incoming packet!!
1 ответ
Эти числа - ваши IP-адреса в десятичном формате. Например, если я запускаю ваш скрипт в одном терминале во время пинга8.8.8.8
в другом я получаю:
term1$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=52 time=9.80 ms
[...]
term2$ python test.py
[...]
ping-6545 [004] .... 1876.984747: 0: sss = 134744072 ping-6545 [004] .... 1876.984763: 0: Incoming packet!
[...]
Номер 134744072
соответствует IP 8.8.8.8
(вы можете использовать онлайн - преобразователи десятичного числа в IP или десятичного в шестнадцатеричный, чтобы проверить это).
Вы можете преобразовать эти числа в обычное представление IP, например,IPAddress
на стороне Python (см. пример bcc tunnel_monitor
), но вам придется использовать перфорированный кольцевой буфер или карту для передачи данных со стороны ядра в пользовательское пространство на стороне Python.