捕获网络数据包是网络分析、安全和调试的重要组成部分。在这篇文章中,我们将探索如何使用Rust和pnet库构建网络数据包捕获工具。
创建一个新的Rust项目:
cargo new pnet_packet_capture
在Cargo.toml文件中添加pnet依赖项:
[dependencies]
pnet = "0.34.0"
在src/main.rs文件中,写入以下代码:
use pnet::{datalink::{self, Channel}, packet::ethernet::EthernetPacket};
fn main() {
// 选取 'en0' 网络接口
let interface = datalink::interfaces().into_iter()
.find(|interface| interface.name == "en0")
.unwrap();
// 抓包需要数据链路通道,它建立了到网络接口'en0' 的底层链路。
let (_, mut rx) = match datalink::channel(&interface, Default::default()) {
Ok(Channel::Ethernet(tx, rx)) => (tx, rx),
Ok(_) => panic!("Unhandled channel type: {}", &interface),
Err(e) => panic!("An error occurred when creating the datalink channel: {}", e),
};
println!("开始读取网络数据包: ");
// 建立一个循环来连续读取传入的数据包
loop {
match rx.next() {
Ok(packet) => {
if let Some(ethernet_packet) = EthernetPacket::new(packet) {
println!("新数据包:");
println!(
"{} => {}: {}",
ethernet_packet.get_destination(),
ethernet_packet.get_source(),
ethernet_packet.get_ethertype()
);
}
},
Err(e) => {
panic!("An error occurred while reading: {}", e);
}
}
}
}
包捕获通常需要以超级用户(根)权限运行:
sudo cargo run
开始读取网络数据包:
新数据包:
04:43:fd:3e:ee:20 => a4:5e:60:ef:b6:73: Ipv4
新数据包:
04:43:fd:3e:ee:20 => a4:5e:60:ef:b6:73: Ipv4
使用以下代码可以获取网络数据包更详细信息:
fn main() {
// 选取 'en0' 网络接口
......
// 建立链路通道
......
println!("开始读取网络数据包: ");
loop {
match rx.next() {
Ok(packet) => {
if let Some(ethernet_packet) = EthernetPacket::new(packet) {
println!("新数据包:");
......
let packet = ethernet_packet.packet();
let payload = ethernet_packet.payload();
let from_packet = ethernet_packet.from_packet();
println!("---");
println!("packet: {:?}", packet);
// 将整个数据包打印为u8数组
println!("payload: {:?}", payload);
// 将有效负载打印为u8数组
println!("from_packet: {:?}", from_packet);
// 打印侦听器信息:MAC地址,以太类型等,有效载荷是u8的数组
println!("---");
}
}
Err(e) => {
panic!("An error occurred while reading: {}", e);
}
}
}
}
使用超级用户权限运行程序时要小心,确保你理解代码并信任正在使用的库。
捕获网络数据包并不复杂,使用Rust和pnet库,可以构建一个安全高效的工具来捕获和分析网络流量。这为网络监控、网络安全和应用程序开发提供了极大的便利。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8