在 Rust 中使用 pnet 捕獲網絡數據包

捕獲網絡數據包是網絡分析、安全和調試的重要組成部分。在這篇文章中,我們將探索如何使用 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 庫,可以構建一個安全高效的工具來捕獲和分析網絡流量。這爲網絡監控、網絡安全和應用程序開發提供了極大的便利。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/S7i4_751Uy8rjG7XfupxZw