在数据链路层拦截数据包

Intercept packets at datalink layer

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

示例代码如下:

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") }
        }
    }
}

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

恐怕不取决于编程语言,而是取决于操作系统。 据我所知,数据包套接字可以 capture/emit 帧但不会拦截它们;这就是防火墙的目的。 非常很久以前,我曾经试验过这个;这是我所知道的。

发生在防火墙内;您必须 modprobe ip_queue 然后添加规则以将数据包发送到该队列 iptables -A OUTPUT -o eth1 -j QUEUE(根据需要调整 input/output/interface)。

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

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

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