在数据链路层拦截数据包
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 选项。
我正在尝试使用 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 选项。