127 lines
4.3 KiB
Rust
127 lines
4.3 KiB
Rust
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::{self, MutableIpv4Packet, Ipv4Packet};
|
|
use pnet::packet::ipv6::{self, MutableIpv6Packet, Ipv6Packet};
|
|
use pnet::packet::tcp::{self, MutableTcpPacket, TcpPacket};
|
|
use pnet::packet::{MutablePacket, Packet};
|
|
use pnet::util::MacAddr;
|
|
use std::env;
|
|
use std::net::Ipv4Addr;
|
|
|
|
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) => {
|
|
match handle_ethernet_frame(packet, own_mac) {
|
|
None => (),//println!("something broke. cool."),
|
|
Some(x) => {
|
|
tx.send_to(x.packet(), None);
|
|
}
|
|
}
|
|
}
|
|
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(MacAddr::new(0xdc, 0xa6, 0x32, 0x49, 0x87, 0xcd));
|
|
//x.set_source(own_mac);
|
|
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(|mut x| {
|
|
let destination = Ipv4Addr::new(192, 168, 129, 12);
|
|
let source = frame.get_source();
|
|
let tcpchecksum = tcp::ipv4_checksum(&x.to_immutable(), &source, &destination);
|
|
x.set_checksum(tcpchecksum);
|
|
|
|
clone.set_payload(x.packet());
|
|
clone.set_destination(destination);
|
|
|
|
let ipchecksum = ipv4::checksum(&clone.to_immutable());
|
|
clone.set_checksum(ipchecksum);
|
|
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<MutableTcpPacket<'a>> {
|
|
match packet.get_destination() {
|
|
80 => {
|
|
let vec: Vec<u8> = packet.packet().to_owned();
|
|
let clone = MutableTcpPacket::owned(vec)?;
|
|
Some(clone)
|
|
}
|
|
_ => {
|
|
//println!("{:?}", &packet);
|
|
None
|
|
},
|
|
}
|
|
}
|