1

我正在尝试使用 rust library 在数据链路层拦截(即消耗而不是捕获)数据包pnet,但是它似乎没有拦截它们,只是读取它们。我不确定是我对网络缺乏了解还是其他原因

这是示例代码:

use pnet::datalink::{self, NetworkInterface, Channel};
use pnet::datalink::Channel::Ethernet;
use pnet::packet::{Packet, MutablePacket};
use pnet::packet::ethernet::{EthernetPacket, MutableEthernetPacket};

use std::env;
use iovec::IoVec;

// Invoke as echo <interface name>
fn main() {
    let interface_name = env::args().nth(1).unwrap();
    let interface_names_match =
        |iface: &NetworkInterface| iface.name == interface_name;

    let interface = datalink::linux::interfaces().into_iter()
        .filter(interface_names_match)
        .next()
        .unwrap();

    let config = datalink::linux::Config::default();
    let channel = datalink::linux::channel(&interface, config).unwrap();



    let (tx, mut rx) = match channel {
        Ethernet(tx, rx) => {
            (tx, rx)
        }
        _ => {panic!("Could not create channel")}
    };

    let mut counter = 0;
    loop {
        match rx.next(){
            Ok(packet) => {
                counter += 1;

                if counter % 1000 == 0 {
                    println!("{}", counter);
                }
            },
            Err(_) => { panic!("Error occured") }
        }
    }
}

我试图拦截我的无线接口。我期望的是,当程序运行时,如果我尝试连接到某个网站,例如,会出现一些网络连接错误,因为浏览器(或客户端)永远不会收到数据包。

4

1 回答 1

2

恐怕它不依赖于编程语言,而是依赖于操作系统。据我所知,数据包套接字可以捕获/发送帧但不拦截它们;这就是防火墙的目的。很久以前,我曾经尝试过这个;这是我所知道的。

它发生在防火墙中;然后,您必须modprobe ip_queue添加一条规则以将数据包发送到该队列iptables -A OUTPUT -o eth1 -j QUEUE(根据需要调整输入/输出/接口)。

然后,您必须在用户空间中构建并运行一个程序,该程序与该队列交互并为每个数据包给出判断(接受/丢弃)。这是在 C 中用<linux/netfilter.h>and完成的-lipq;我不知道你是否可以轻松地在 Rust 中做同样的事情。

顺便说一句,也许最好的解决方案不是依赖用户空间进程给出判决,而只是依赖通常的防火墙规则(如果判决的标准不是太复杂的话)。存在许多启用许多复杂规则的模块和 iptables 选项。

https://linux.die.net/man/3/libipq

于 2021-02-01T10:34:30.697 回答