This commit is contained in:
hexchen 2020-05-02 20:36:19 +00:00
parent c511a00ba3
commit 2ce8203628
2 changed files with 111 additions and 0 deletions

View file

@ -7,3 +7,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
pnet = "*"

110
src/main.rs Normal file
View file

@ -0,0 +1,110 @@
extern crate pnet;
use pnet::datalink::Channel::Ethernet;
use pnet::datalink::{self, NetworkInterface};
use pnet::packet::ethernet::{EtherTypes, EthernetPacket, MutableEthernetPacket};
use pnet::packet::ip::IpNextHeaderProtocols;
use pnet::packet::ipv4::{MutableIpv4Packet, Ipv4Packet};
use pnet::packet::ipv6::{MutableIpv6Packet, Ipv6Packet};
use pnet::packet::tcp::TcpPacket;
use pnet::packet::{MutablePacket, Packet};
use pnet::util::MacAddr;
use std::env;
fn main() {
let interface_name = env::args().nth(1).unwrap();
let interface_names_match = |iface: &NetworkInterface| iface.name == interface_name;
let interfaces = datalink::interfaces();
let interface = interfaces.into_iter().find(interface_names_match).unwrap();
let own_mac = interface.mac.unwrap();
let (mut 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) => {
if handle_ethernet_frame(packet, own_mac).is_none() {
println!("something broke. cool.");
}
}
Err(e) => {
// If an error occurs, we can handle it here
panic!("An error occurred while reading: {}", e);
}
}
}
}
fn handle_ethernet_frame(packet: &[u8], own_mac: MacAddr) -> Option<EthernetPacket> {
let frame = EthernetPacket::new(packet)?;
// frame is originating from us, we want to ignore it.
// same if it's not addressed to our mac
if frame.get_source() == own_mac || frame.get_destination() != own_mac {
return None;
}
let vec: Vec<u8> = frame.packet().to_owned();
let mut clone = MutableEthernetPacket::owned(vec)?;
let ret = match frame.get_ethertype() {
EtherTypes::Ipv4 => {
clone.set_payload(handle_ipv4_frame(&frame)?.packet());
Some(clone)
},
EtherTypes::Ipv6 => {
clone.set_payload(handle_ipv6_frame(&frame)?.packet());
Some(clone)
},
_ => None,
};
ret.map(|mut x| {
x.set_destination(frame.get_source());
x.set_source(frame.get_destination());
x.consume_to_immutable()
})
}
fn handle_ipv4_frame<'a>(ether_frame: &EthernetPacket) -> Option<Ipv4Packet<'a>> {
let frame = Ipv4Packet::new(ether_frame.payload())?;
let vec: Vec<u8> = frame.packet().to_owned();
let mut clone = MutableIpv4Packet::owned(vec)?;
let ret = match frame.get_next_level_protocol() {
IpNextHeaderProtocols::Tcp => handle_tcp_frame(&TcpPacket::new(frame.payload())?),
_ => None,
};
ret.map(|x| {
clone.set_payload(x.packet());
clone.consume_to_immutable()
})
}
fn handle_ipv6_frame<'a>(ether_frame: &EthernetPacket) -> Option<Ipv6Packet<'a>> {
let frame = Ipv6Packet::new(ether_frame.payload())?;
let vec: Vec<u8> = frame.packet().to_owned();
let mut clone = MutableIpv6Packet::owned(vec)?;
let ret = match frame.get_next_header() {
IpNextHeaderProtocols::Tcp => handle_tcp_frame(&TcpPacket::new(frame.payload())?),
_ => None,
};
ret.map(|x| {
clone.set_payload(x.packet());
clone.consume_to_immutable()
})
}
fn handle_tcp_frame<'a>(packet: &TcpPacket) -> Option<TcpPacket<'a>> {
println!("{:?}", packet);
match packet.get_destination() {
80 => {
let vec: Vec<u8> = packet.packet().to_owned();
TcpPacket::owned(vec)
}
_ => None,
}
}