美文网首页RUST编程
007 Rust 网络编程,libpnet 库介绍

007 Rust 网络编程,libpnet 库介绍

作者: 令狐壹冲 | 来源:发表于2020-05-05 15:49 被阅读0次

    pnet

    libpnet为Rust提供一组跨平台的底层网络API。

    依赖

    [dependencies]
    pnet = "0.25.0"
    

    源码示例

    use pnet::datalink::Channel::Ethernet;
    use pnet::datalink::{self, NetworkInterface};
    use pnet::packet::ethernet::{EtherTypes, EthernetPacket};
    use pnet::packet::ip::IpNextHeaderProtocols;
    use pnet::packet::ipv4::Ipv4Packet;
    use pnet::packet::tcp::TcpPacket;
    use pnet::packet::Packet;
    
    use std::env;
    
    fn handle_packet(ethernet: &EthernetPacket) {
        // 对Ipv4的包按层解析
        match ethernet.get_ethertype() {
            EtherTypes::Ipv4 => {
                let header = Ipv4Packet::new(ethernet.payload());
                if let Some(header) = header {
                    match header.get_next_level_protocol() {
                        IpNextHeaderProtocols::Tcp => {
                            let tcp = TcpPacket::new(header.payload());
                            if let Some(tcp) = tcp {
                                println!(
                                    "Got a TCP packet {}:{} to {}:{}",
                                    header.get_source(),
                                    tcp.get_source(),
                                    header.get_destination(),
                                    tcp.get_destination()
                                );
                            }
                        }
                        _ => println!("Ignoring non TCP packet"),
                    }
                }
            }
            _ => println!("Ignoring non IPv4 packet"),
        }
    }
    
    fn main() {
        let interface_name = env::args().nth(1).unwrap();
    
        // 获取网卡列表
        let interfaces = datalink::interfaces();
        let interface = interfaces
            .into_iter()
            .filter(|iface: &NetworkInterface| iface.name == interface_name)
            .next()
            .expect("Error getting interface");
    
        let (_tx, mut rx) = match datalink::channel(&interface, Default::default()) {
            Ok(Ethernet(tx, rx)) => (tx, rx),
            Ok(_) => panic!("Unhandled channel type"),
            Err(e) => panic!(
                "An error occurred when creating the datalink channel: {}",
                e
            ),
        };
    
        loop {
            // 获取收到的包
            match rx.next() {
                Ok(packet) => {
                    let packet = EthernetPacket::new(packet).unwrap();
                    handle_packet(&packet);
                }
                Err(e) => {
                    panic!("An error occurred while reading: {}", e);
                }
            }
        }
    }
    

    运行:

    sudo cargo run 网卡名字  //例子:sudo cargo run enp0s3
    

    相关文章

      网友评论

        本文标题:007 Rust 网络编程,libpnet 库介绍

        本文链接:https://www.haomeiwen.com/subject/ikimghtx.html