mod args;
use pnet::{
datalink::{self},
packet::{
Packet,
ethernet::{EtherTypes, EthernetPacket},
ip::IpNextHeaderProtocols,
ipv4::Ipv4Packet,
tcp::TcpPacket,
},
};
use args::Args;
use clap::Parser;
fn main() {
let args = Args::parse();
let interfaces = datalink::interfaces();
let interface = if let Some(ref name) = args.iface {
interfaces
.into_iter()
.find(|iface| iface.name == *name)
.expect("指定的网卡没找到")
} else {
interfaces
.into_iter()
.find(|iface| !iface.is_loopback() && iface.is_up())
.expect("找不到可用的网络接口")
};
println!("使用网络接口:{}", interface.name);
let mut rx = match datalink::channel(&interface, Default::default()) {
Ok(datalink::Channel::Ethernet(_, rx)) => rx,
Ok(_) => panic!("不支持的通道类型"),
Err(e) => panic!("无法创建通道:{}", e),
};
loop {
match rx.next() {
Ok(packet) => {
let eth_packet = match EthernetPacket::new(packet) {
Some(p) => p,
None => continue,
};
if eth_packet.get_ethertype() == EtherTypes::Ipv4 {
if let Some(ipv4) = Ipv4Packet::new(eth_packet.payload()) {
if ipv4.get_next_level_protocol() == IpNextHeaderProtocols::Tcp {
if let Some(tcp) = TcpPacket::new(ipv4.payload()) {
if let Some(filter_ip) = args.src_ip {
if ipv4.get_source() != filter_ip {
continue;
}
}
if let Some(filter_ip) = args.dst_ip {
if ipv4.get_destination()!= filter_ip {
continue;
}
}
if let Some(filter_port) = args.src_port {
if tcp.get_source() != filter_port {
continue;
}
}
if let Some(filter_port) = args.dst_port {
if tcp.get_destination() != filter_port {
continue;
}
}
println!(
"TCP包: {}:{} -> {}:{} | seq={} Ack={} Len={}",
ipv4.get_source(),
tcp.get_source(),
ipv4.get_destination(),
tcp.get_destination(),
tcp.get_sequence(),
tcp.get_acknowledgement(),
tcp.payload().len()
);
print_payload(tcp.payload());
}
}
}
}
}
Err(e) => {
eprintln!("读取数据包错误:{}", e)
}
}
}
}
fn print_payload(payload: &[u8]) {
const MAX_LEN: usize = 512;
let len = payload.len().min(MAX_LEN);
if len == 0 {
println!(" 数据:<空>");
return;
}
print!(" 十六进制:");
for byte in &payload[..len] {
print!("{:02X}", byte);
}
println!();
print!(" ASCII:");
for byte in &payload[..len] {
if byte.is_ascii_graphic() || *byte == b' ' {
print!("{}", *byte as char);
} else {
print!(".")
}
}
parse_http(payload);
println!("\n===================================\n")
}
fn parse_http(payload: &[u8]) {
if payload.is_empty() {
return;
}
if let Ok(text) = std::str::from_utf8(payload) {
if text.starts_with("GET ") || text.starts_with("POST ") || text.starts_with("HTTP/") {
println!("---------- HTTP 数据开始 ----------");
for line in text.lines().take(20) {
println!(" {}", line);
if line.is_empty() {
break; }
}
println!("---------- HTTP 数据结束 ----------\n");
}
}
}