环境
- Time 2022-11-20
- WSL-Ubuntu 22.04
- Rust 1.65.0
- pnet 0.31.0
- tun-tap 0.1.3
前言
说明
参考:https://docs.rs/pnet_packet/latest/pnet_packet/index.html
参考:https://www.kernel.org/doc/html/latest/networking/tuntap.html
目标
使用 TAP 后,接收到 ARP 操作系统不再自动回应,编写一个自己的回应消息。
发送 ARP 请求还是使用之前编写好的,同时 TAP 也是使用之前建好的。
判断 ARP 协议
use pnet_packet::arp::{ArpHardwareTypes, ArpOperations};
use pnet_packet::arp::{ArpPacket, MutableArpPacket};
use pnet_packet::ethernet::MutableEthernetPacket;
use pnet_packet::ethernet::{EtherTypes, EthernetPacket};
use pnet_packet::MutablePacket;
use tun_tap::{Iface, Mode};
fn main() -> std::io::Result<()> {
let iface = Iface::without_packet_info("tap0", Mode::Tap)?;
let mut buffer = vec![0; 1500];
loop {
let size = iface.recv(&mut buffer)?;
let ethernet = EthernetPacket::new(&buffer).unwrap();
if EtherTypes::Arp == ethernet.get_ethertype() {
println!("{:?}", &buffer[..size]);
}
}
}
构造以太网协议
let packet = ArpPacket::new(&buffer[EthernetPacket::minimum_packet_size()..]).unwrap();
let mut content = [0; 42];
let mut eth = MutableEthernetPacket::new(&mut content).unwrap();
eth.set_destination(ethernet.get_source());
eth.set_source("44:44:44:44:44:44".parse().unwrap());
eth.set_ethertype(EtherTypes::Arp);
地址解析协议还是使用之前的一篇的 ARP 请求。
构造 ARP 回应
let mut buf = [0; 28];
let mut arp = MutableArpPacket::new(&mut buf).unwrap();
arp.set_hardware_type(ArpHardwareTypes::Ethernet);
arp.set_protocol_type(EtherTypes::Ipv4);
arp.set_hw_addr_len(6);
arp.set_proto_addr_len(4);
arp.set_operation(ArpOperations::Reply);
arp.set_sender_hw_addr("44:44:44:44:44:44".parse().unwrap());
arp.set_sender_proto_addr(packet.get_target_proto_addr());
arp.set_target_hw_addr(packet.get_sender_hw_addr());
arp.set_target_proto_addr(packet.get_sender_proto_addr());
eth.set_payload(arp.packet_mut());
发送回应
iface.send(eth.packet_mut()).unwrap();
抓包结果
20:20:05.230635 ea:f3:f5:24:7a:dd > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 172.24.51.244 tell 172.24.51.244, length 28
0x0000: 0001 0800 0604 0001 eaf3 f524 7add ac18 ...........$z...
0x0010: 33f4 0000 0000 0000 ac18 33f4 3.........3.
20:20:05.230718 44:44:44:44:44:44 > ea:f3:f5:24:7a:dd, ethertype ARP (0x0806), length 42: Reply 172.24.51.244 is-at 44:44:44:44:44:44, length 28
0x0000: 0001 0800 0604 0002 4444 4444 4444 ac18 ........DDDDDD..
0x0010: 33f4 eaf3 f524 7add ac18 33f4 3....$z...3.
程序输出
Sent ARP request
Received reply: 44:44:44:44:44:44
总结
使用 TAP 设备,模拟了 ARP 请求和回应,并通过抓包工具进行查看。
附录
Cargo.toml
[package]
edition = "2021"
name = "network"
version = "1.0.0"
[dependencies]
pnet_datalink = "0.31.0"
pnet_packet = "0.31.0"
tun-tap = "0.1.3"
main.rs
use pnet_packet::arp::{ArpHardwareTypes, ArpOperations};
use pnet_packet::arp::{ArpPacket, MutableArpPacket};
use pnet_packet::ethernet::MutableEthernetPacket;
use pnet_packet::ethernet::{EtherTypes, EthernetPacket};
use pnet_packet::MutablePacket;
use tun_tap::{Iface, Mode};
fn main() -> std::io::Result<()> {
let iface = Iface::without_packet_info("tap0", Mode::Tap)?;
let mut buffer = vec![0; 1500];
loop {
let size = iface.recv(&mut buffer)?;
let ethernet = EthernetPacket::new(&buffer).unwrap();
if EtherTypes::Arp == ethernet.get_ethertype() {
println!("{:?}", &buffer[..size]);
let packet = ArpPacket::new(&buffer[EthernetPacket::minimum_packet_size()..]).unwrap();
let mut content = [0; 42];
let mut eth = MutableEthernetPacket::new(&mut content).unwrap();
eth.set_destination(ethernet.get_source());
eth.set_source("44:44:44:44:44:44".parse().unwrap());
eth.set_ethertype(EtherTypes::Arp);
let mut buf = [0; 28];
let mut arp = MutableArpPacket::new(&mut buf).unwrap();
arp.set_hardware_type(ArpHardwareTypes::Ethernet);
arp.set_protocol_type(EtherTypes::Ipv4);
arp.set_hw_addr_len(6);
arp.set_proto_addr_len(4);
arp.set_operation(ArpOperations::Reply);
arp.set_sender_hw_addr("44:44:44:44:44:44".parse().unwrap());
arp.set_sender_proto_addr(packet.get_target_proto_addr());
arp.set_target_hw_addr(packet.get_sender_hw_addr());
arp.set_target_proto_addr(packet.get_sender_proto_addr());
eth.set_payload(arp.packet_mut());
println!("s: {:?}", eth.packet_mut());
iface.send(eth.packet_mut()).unwrap();
}
}
}
sender.rs
use std::net::IpAddr;
use pnet_datalink::{channel, Channel, MacAddr};
use pnet_packet::arp::{ArpHardwareTypes, ArpOperations, ArpPacket, MutableArpPacket};
use pnet_packet::ethernet::EtherTypes;
use pnet_packet::{ethernet::MutableEthernetPacket, MutablePacket, Packet};
fn main() {
let interface = pnet_datalink::interfaces()
.into_iter()
.find(|iface| iface.name == "tap0")
.unwrap();
let channel = channel(&interface, Default::default());
let (mut sender, mut reader) = match channel {
Ok(Channel::Ethernet(tx, rx)) => (tx, rx),
_ => panic!("Not a valid channel returned"),
};
let mut buffer = [0; 42];
let mut ethernet = MutableEthernetPacket::new(&mut buffer).unwrap();
ethernet.set_destination(MacAddr::broadcast());
ethernet.set_source(interface.mac.unwrap());
ethernet.set_ethertype(EtherTypes::Arp);
let mut buffer = [0; 28];
let mut arp = MutableArpPacket::new(&mut buffer).unwrap();
let ip = interface.ips.get(0).unwrap();
let source_ip = match ip.ip() {
IpAddr::V4(ip) => ip,
_ => unreachable!(),
};
arp.set_hardware_type(ArpHardwareTypes::Ethernet);
arp.set_protocol_type(EtherTypes::Ipv4);
arp.set_hw_addr_len(6);
arp.set_proto_addr_len(4);
arp.set_operation(ArpOperations::Request);
arp.set_sender_hw_addr(interface.mac.unwrap());
arp.set_sender_proto_addr(source_ip);
arp.set_target_hw_addr(MacAddr::zero());
arp.set_target_proto_addr("172.24.51.244".parse().unwrap());
ethernet.set_payload(arp.packet_mut());
sender.send_to(ethernet.packet(), None).unwrap().unwrap();
println!("Sent ARP request");
loop {
let buf = reader.next().unwrap();
let arp = ArpPacket::new(&buf[MutableEthernetPacket::minimum_packet_size()..]).unwrap();
println!("Received reply: {:?}", arp.get_sender_hw_addr());
}
}
标签:ARP,arp,set,mut,0220,44,packet,发送,let
From: https://www.cnblogs.com/jiangbo4444/p/18354349