pnet
libpnet為Rust提供一組跨平臺的底層網路API。
依賴
[dependencies]
pnet = “0。25。0”
原始碼示例
use pnet::datalink::Channel::Ethernet;
use pnet::datalink::;
use pnet::packet::ethernet::;
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