【问题标题】:eBPF packet filter not giving me correct dataeBPF 数据包过滤器没有给我正确的数据
【发布时间】:2020-04-23 18:23:58
【问题描述】:

所以我一直在尝试查看是否可以将 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!!

【问题讨论】:

    标签: bpf ebpf bcc-bpf


    【解决方案1】:

    这些数字是您的 IP 地址,采用十进制格式。例如,如果我在一个终端上启动您的脚本,而在另一个终端上 ping 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对应IP8.8.8.8(您可以使用在线decimal-to-IPdecimal-to-hex转换器来检查)。

    您可以将这些数字转换为通常的 IP 表示,例如在 Python 端使用 IPAddress(参见 bcc 的示例 tunnel_monitor),但您必须使用 perf 环形缓冲区或映射将数据从内核端传输到用户空间,Python 端。

    【讨论】:

    • 非常感谢您的帮助!另外,如果您不介意我问,如果我想将检索到的每一个数据传输到用户空间并尝试将其保存在数据库中,您会推荐 perf_event_array 映射吗?我已经进行了一些研究,并建议将其用于此类任务。但是,我认为我没有看到他们将此映射与套接字缓冲区一起使用的示例。我见过的所有例子都是用ctx的。我确实读过它可以与套接字缓冲区一起使用吗?但我不太确定,因为我还没有见过。谢谢你的一切!
    • 哦,实际上我刚刚找到了一个使用 skb 和 perf_output 的示例。非常感谢您的帮助:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多