feat: added the ability to respond to ARP requests
This commit is contained in:
parent
0bda72491c
commit
0bb2871568
@ -1,4 +1,9 @@
|
|||||||
use std::{io::prelude::*, net::UdpSocket, thread, sync::{Arc, Mutex, Condvar}};
|
use std::{
|
||||||
|
io::prelude::*,
|
||||||
|
net::UdpSocket,
|
||||||
|
sync::{Arc, Condvar, Mutex},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use ed25519_dalek::{Keypair, Signer};
|
use ed25519_dalek::{Keypair, Signer};
|
||||||
@ -17,7 +22,7 @@ impl Msg<'_> {
|
|||||||
0 => Some(Msg::Ready(bytes[1])),
|
0 => Some(Msg::Ready(bytes[1])),
|
||||||
1 => Some(Msg::Stdout(&bytes[1..])),
|
1 => Some(Msg::Stdout(&bytes[1..])),
|
||||||
2 => Some(Msg::Stderr(&bytes[1..])),
|
2 => Some(Msg::Stderr(&bytes[1..])),
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,8 +52,12 @@ fn main() -> anyhow::Result<()> {
|
|||||||
let mut buffer = [0u8; 1536];
|
let mut buffer = [0u8; 1536];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let Ok(amount) = remote_listen.recv(&mut buffer[..]) else { continue; };
|
let Ok(amount) = remote_listen.recv(&mut buffer[..]) else {
|
||||||
let Some(msg) = Msg::parse(&buffer[..amount]) else { continue; };
|
continue;
|
||||||
|
};
|
||||||
|
let Some(msg) = Msg::parse(&buffer[..amount]) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
match msg {
|
match msg {
|
||||||
Msg::Ready(_) => {
|
Msg::Ready(_) => {
|
||||||
@ -59,12 +68,14 @@ fn main() -> anyhow::Result<()> {
|
|||||||
};
|
};
|
||||||
*inuse = false;
|
*inuse = false;
|
||||||
cvar.notify_one();
|
cvar.notify_one();
|
||||||
},
|
}
|
||||||
Msg::Stderr(err) => {
|
Msg::Stderr(err) => {
|
||||||
let _ = stderr.write(err);
|
let _ = stderr.write(err);
|
||||||
},
|
}
|
||||||
Msg::Stdout(out) => {
|
Msg::Stdout(out) => {
|
||||||
let Ok(mut stdout) = stdout_arc.lock() else { continue; };
|
let Ok(mut stdout) = stdout_arc.lock() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
let _ = stdout.write(out);
|
let _ = stdout.write(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,13 +103,19 @@ fn main() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let Ok(mut stdout) = stdout_arc.lock() else { continue; };
|
let Ok(mut stdout) = stdout_arc.lock() else {
|
||||||
let Ok(_) = write!(&*stdout, "root@{}:{} # ", &target, &cwd) else { continue; };
|
continue;
|
||||||
|
};
|
||||||
|
let Ok(_) = write!(&*stdout, "root@{}:{} # ", &target, &cwd) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
let _ = stdout.flush();
|
let _ = stdout.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cmd = String::new();
|
let mut cmd = String::new();
|
||||||
let Ok(amount) = stdin.read_line(&mut cmd) else { continue; };
|
let Ok(amount) = stdin.read_line(&mut cmd) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
let mut cmd = cmd.trim();
|
let mut cmd = cmd.trim();
|
||||||
|
|
||||||
if amount == 0 {
|
if amount == 0 {
|
||||||
@ -113,8 +130,10 @@ fn main() -> anyhow::Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match cmd.split(" ").collect::<Vec<_>>()[..] {
|
match cmd.split(" ").collect::<Vec<_>>()[..] {
|
||||||
["exit"] => { break },
|
["exit"] => break,
|
||||||
["cd", dir] => { cwd = dir.to_owned(); },
|
["cd", dir] => {
|
||||||
|
cwd = dir.to_owned();
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let (lock, _) = &*stdout_inuse;
|
let (lock, _) = &*stdout_inuse;
|
||||||
let Ok(mut inuse) = lock.lock() else {
|
let Ok(mut inuse) = lock.lock() else {
|
||||||
|
|||||||
@ -6,7 +6,9 @@ fn main() -> anyhow::Result<()> {
|
|||||||
loop {
|
loop {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
|
|
||||||
let Ok((amount, src)) = input.recv_from(&mut buf[..]) else { continue; };
|
let Ok((amount, src)) = input.recv_from(&mut buf[..]) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
if amount != 4 {
|
if amount != 4 {
|
||||||
continue;
|
continue;
|
||||||
@ -14,6 +16,8 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
println!("Received packet: {}", i32::from_be_bytes(buf));
|
println!("Received packet: {}", i32::from_be_bytes(buf));
|
||||||
|
|
||||||
let Ok(_) = input.send_to(&buf, src) else { continue; };
|
let Ok(_) = input.send_to(&buf, src) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,17 @@ impl<'a> EthernetPkt<'a> {
|
|||||||
|
|
||||||
Ok(Layer3Pkt::IPv4Pkt(pkt))
|
Ok(Layer3Pkt::IPv4Pkt(pkt))
|
||||||
}
|
}
|
||||||
|
0x0806 => {
|
||||||
|
if self.data.len() < 42 {
|
||||||
|
return Err(error::Error::PacketLengthInvalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pkt = ARPPkt {
|
||||||
|
data: &self.data[14..],
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Layer3Pkt::ARP(pkt))
|
||||||
|
}
|
||||||
p => Err(error::Error::UnknownPacketType(p)),
|
p => Err(error::Error::UnknownPacketType(p)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,6 +82,7 @@ impl<'a> EthernetPkt<'a> {
|
|||||||
|
|
||||||
pub enum Layer3Pkt<'a> {
|
pub enum Layer3Pkt<'a> {
|
||||||
IPv4Pkt(IPv4Pkt<'a>),
|
IPv4Pkt(IPv4Pkt<'a>),
|
||||||
|
ARP(ARPPkt<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IPv4Pkt<'a> {
|
pub struct IPv4Pkt<'a> {
|
||||||
@ -160,6 +172,51 @@ impl<'a> IPv4Pkt<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ARPPkt<'a> {
|
||||||
|
data: &'a [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ARPPkt<'a> {
|
||||||
|
pub fn htype(&self) -> u16 {
|
||||||
|
u16::from_be_bytes(self.data[0..2].try_into().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ptype(&self) -> u16 {
|
||||||
|
u16::from_be_bytes(self.data[2..4].try_into().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hwlen(&self) -> u8 {
|
||||||
|
self.data[4]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn plen(&self) -> u8 {
|
||||||
|
self.data[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn opcode(&self) -> u16 {
|
||||||
|
u16::from_be_bytes(self.data[6..8].try_into().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn srchwaddr(&self) -> &[u8] {
|
||||||
|
&self.data[8usize..8usize + self.hwlen() as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn srcprotoaddr(&self) -> &[u8] {
|
||||||
|
let start = self.hwlen() as usize + 8;
|
||||||
|
&self.data[start..start + self.plen() as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn targethwaddr(&self) -> &[u8] {
|
||||||
|
let start = self.hwlen() as usize + self.plen() as usize + 8;
|
||||||
|
&self.data[start..start + self.hwlen() as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn targetprotoaddr(&self) -> &[u8] {
|
||||||
|
let start = self.hwlen() as usize + self.plen() as usize + self.hwlen() as usize + 8;
|
||||||
|
&self.data[start..start + self.plen() as usize]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum Layer4Pkt<'a> {
|
pub enum Layer4Pkt<'a> {
|
||||||
UDP(UDPPkt<'a>),
|
UDP(UDPPkt<'a>),
|
||||||
TCP(TCPPkt<'a>),
|
TCP(TCPPkt<'a>),
|
||||||
@ -169,7 +226,7 @@ impl<'a> Layer4Pkt<'a> {
|
|||||||
pub fn len(&self) -> u16 {
|
pub fn len(&self) -> u16 {
|
||||||
match self {
|
match self {
|
||||||
Layer4Pkt::UDP(pkt) => pkt.len(),
|
Layer4Pkt::UDP(pkt) => pkt.len(),
|
||||||
Layer4Pkt::TCP(_) => 0,
|
Layer4Pkt::TCP(pkt) => pkt.data.len() as u16,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,6 +415,9 @@ impl EthernetPacket {
|
|||||||
Layer3Packet::IPv4(pkt) => EthernetPacket {
|
Layer3Packet::IPv4(pkt) => EthernetPacket {
|
||||||
data: [&dst[..], &src[..], &[0x08_u8, 0x00_u8][..], &*pkt.data].concat(),
|
data: [&dst[..], &src[..], &[0x08_u8, 0x00_u8][..], &*pkt.data].concat(),
|
||||||
},
|
},
|
||||||
|
Layer3Packet::ARP(pkt) => EthernetPacket {
|
||||||
|
data: [&dst[..], &src[..], &[0x08_u8, 0x06_u8][..], &*pkt.data].concat(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,13 +430,74 @@ impl EthernetPacket {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Layer3Packet {
|
pub enum Layer3Packet {
|
||||||
IPv4(IPv4Packet),
|
IPv4(IPv4Packet),
|
||||||
|
ARP(ARPPacket),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ARPPacket {
|
||||||
|
data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ARPMode {
|
||||||
|
Request,
|
||||||
|
Reply,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ARPMode {
|
||||||
|
fn opcode(&self) -> u16 {
|
||||||
|
match self {
|
||||||
|
Self::Request => 1,
|
||||||
|
Self::Reply => 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ARPProto {
|
||||||
|
IPv4,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ARPProto {
|
||||||
|
fn opcode(&self) -> u16 {
|
||||||
|
match self {
|
||||||
|
Self::IPv4 => 0x0800,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ARPPacket {
|
||||||
|
pub fn construct(
|
||||||
|
op: ARPMode,
|
||||||
|
proto: ARPProto,
|
||||||
|
srchwaddr: &[u8],
|
||||||
|
targethwaddr: &[u8],
|
||||||
|
srcprotoaddr: &[u8],
|
||||||
|
targetprotoaddr: &[u8],
|
||||||
|
) -> ARPPacket {
|
||||||
|
assert!(srchwaddr.len() == targethwaddr.len());
|
||||||
|
assert!(srcprotoaddr.len() == targetprotoaddr.len());
|
||||||
|
|
||||||
|
let data = [
|
||||||
|
&0x0001u16.to_be_bytes()[..],
|
||||||
|
&proto.opcode().to_be_bytes()[..],
|
||||||
|
&[srchwaddr.len() as u8],
|
||||||
|
&[srcprotoaddr.len() as u8],
|
||||||
|
&op.opcode().to_be_bytes(),
|
||||||
|
srchwaddr,
|
||||||
|
srcprotoaddr,
|
||||||
|
targethwaddr,
|
||||||
|
targetprotoaddr,
|
||||||
|
]
|
||||||
|
.concat();
|
||||||
|
|
||||||
|
ARPPacket { data }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static IPV4_ID: AtomicU16 = AtomicU16::new(0xabcd);
|
static IPV4_ID: AtomicU16 = AtomicU16::new(0xabcd);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct IPv4Packet {
|
pub struct IPv4Packet {
|
||||||
data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IPv4Packet {
|
impl IPv4Packet {
|
||||||
|
|||||||
@ -10,8 +10,8 @@ use log::{debug, error, info, trace};
|
|||||||
use nl_sys::{netlink, route};
|
use nl_sys::{netlink, route};
|
||||||
|
|
||||||
use packets::{
|
use packets::{
|
||||||
self, EthernetPacket, IPv4Packet, IPv4Pkt, Layer3Packet, Layer3Pkt, Layer4Packet, Layer4Pkt,
|
self, ARPMode, ARPPacket, ARPProto, EthernetPacket, IPv4Packet, IPv4Pkt, Layer3Packet,
|
||||||
TCPPacket, TCPPacketBuilder, TCPPkt,
|
Layer3Pkt, Layer4Packet, Layer4Pkt, TCPPacket, TCPPacketBuilder, TCPPkt,
|
||||||
};
|
};
|
||||||
use pcap_sys;
|
use pcap_sys;
|
||||||
use tokio::{sync::mpsc, task};
|
use tokio::{sync::mpsc, task};
|
||||||
@ -71,7 +71,7 @@ impl TcpOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn socket_accepts_packet(socket: &TcpSocket, ip: IPv4Pkt<'_>, tcp: TCPPkt<'_>) -> bool {
|
fn socket_accepts_packet(socket: &TcpSocket, ip: &IPv4Pkt<'_>, tcp: &TCPPkt<'_>) -> bool {
|
||||||
if let Some(peer) = &socket.peer_info {
|
if let Some(peer) = &socket.peer_info {
|
||||||
peer.local_addr == ip.dest_ip()
|
peer.local_addr == ip.dest_ip()
|
||||||
&& peer.remote_addr == ip.source_ip()
|
&& peer.remote_addr == ip.source_ip()
|
||||||
@ -110,7 +110,7 @@ fn connect(
|
|||||||
.syn(true)
|
.syn(true)
|
||||||
.window(64240)
|
.window(64240)
|
||||||
.seqnumber(socket.local_seq_no)
|
.seqnumber(socket.local_seq_no)
|
||||||
.options([TcpOptions::MaxSegmentSize(64240).get_bytes()].concat())
|
//.options([TcpOptions::MaxSegmentSize(64240).get_bytes()].concat())
|
||||||
.build(local_addr, remote_addr, vec![], None);
|
.build(local_addr, remote_addr, vec![], None);
|
||||||
|
|
||||||
(local_port, packet)
|
(local_port, packet)
|
||||||
@ -127,8 +127,11 @@ fn process_packet(
|
|||||||
Ok((None, None))
|
Ok((None, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_data(socket: &mut TcpSocket, data: Vec<u8>) -> anyhow::Result<(TCPPacketBuilder, Vec<u8>)> {
|
fn send_data(
|
||||||
Ok(todo!())
|
socket: &mut TcpSocket,
|
||||||
|
data: Vec<u8>,
|
||||||
|
) -> anyhow::Result<Option<(TCPPacketBuilder, Vec<u8>)>> {
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TcpSocketHandle {
|
struct TcpSocketHandle {
|
||||||
@ -167,7 +170,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.ok_or(anyhow!("could not get target IP"))?
|
.ok_or(anyhow!("could not get target IP"))?
|
||||||
.parse::<Ipv4Addr>()?;
|
.parse::<Ipv4Addr>()?;
|
||||||
|
|
||||||
let (routes, (ifname, ifindex, srcip, src_mac, dst_mac, src_snmask)) = {
|
let (ifname, _, srcip, src_mac, dst_mac, _) = {
|
||||||
let socket = netlink::Socket::new()?;
|
let socket = netlink::Socket::new()?;
|
||||||
|
|
||||||
let routes = socket.get_routes()?;
|
let routes = socket.get_routes()?;
|
||||||
@ -175,16 +178,21 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let links = socket.get_links()?;
|
let links = socket.get_links()?;
|
||||||
let addrs = socket.get_addrs()?;
|
let addrs = socket.get_addrs()?;
|
||||||
|
|
||||||
let res = route::get_macs_and_src_for_ip(&addrs, &routes, &neighs, &links, ip)
|
route::get_macs_and_src_for_ip(&addrs, &routes, &neighs, &links, ip)
|
||||||
.ok_or(anyhow!("unable to find a route to the IP"))?;
|
.ok_or(anyhow!("unable to find a route to the IP"))?
|
||||||
|
|
||||||
(routes, res)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut socket = TcpSocket::default();
|
let mut socket = TcpSocket::default();
|
||||||
|
|
||||||
let mut interface = pcap_sys::Interface::<pcap_sys::DevDisabled>::new(&ifname)?;
|
let mut interface = pcap_sys::Interface::<pcap_sys::DevDisabled>::new(&ifname)?;
|
||||||
|
|
||||||
|
let srcip: u32 = srcip.into();
|
||||||
|
let srcip = srcip + 10;
|
||||||
|
let srcip: Ipv4Addr = srcip.into();
|
||||||
|
dbg!(srcip, src_mac, dst_mac);
|
||||||
|
|
||||||
|
let dst_mac = [0x00, 0x16, 0x3e, 0xde, 0xa9, 0x93];
|
||||||
|
|
||||||
interface.set_buffer_size(8192)?;
|
interface.set_buffer_size(8192)?;
|
||||||
interface.set_non_blocking(true)?;
|
interface.set_non_blocking(true)?;
|
||||||
interface.set_promisc(false)?;
|
interface.set_promisc(false)?;
|
||||||
@ -194,18 +202,14 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
macro_rules! format_packet {
|
macro_rules! format_packet {
|
||||||
($tcp_packet:expr) => {{
|
($tcp_packet:expr) => {{
|
||||||
let layer3pkt = Layer3Packet::IPv4(IPv4Packet::construct(
|
let ippkt = IPv4Packet::construct(srcip, ip, &Layer4Packet::TCP($tcp_packet));
|
||||||
srcip,
|
EthernetPacket::construct(src_mac, dst_mac, &Layer3Packet::IPv4(ippkt))
|
||||||
ip,
|
|
||||||
&Layer4Packet::TCP($tcp_packet),
|
|
||||||
));
|
|
||||||
EthernetPacket::construct(src_mac, dst_mac, &layer3pkt)
|
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
let (port, packet) = connect(&mut socket, ip, 54248, srcip);
|
let (port, packet) = connect(&mut socket, ip, 54248, srcip);
|
||||||
|
|
||||||
interface.set_filter(&format!("inbound and tcp port {port}"), true, None)?;
|
interface.set_filter(&format!("arp or (inbound and tcp port {port})"), true, None)?;
|
||||||
|
|
||||||
if interface.datalink() != pcap_sys::consts::DLT_EN10MB {
|
if interface.datalink() != pcap_sys::consts::DLT_EN10MB {
|
||||||
bail!("interface does not support ethernet");
|
bail!("interface does not support ethernet");
|
||||||
@ -226,23 +230,50 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
task::spawn(async move { use_socket(socket_handle) });
|
task::spawn(async move { use_socket(socket_handle) });
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let Some((builder, data)) = tokio::select! {
|
let Some(packet) = tokio::select! {
|
||||||
Some(Ok(bytes)) = packets.next() => {
|
Some(Ok(bytes)) = packets.next() => {
|
||||||
let pkt = bytes.pkt();
|
let pkt = bytes.pkt();
|
||||||
let Ok(Layer3Pkt::IPv4Pkt(ip_pkt)) = pkt.get_layer3_pkt() else { continue; };
|
|
||||||
|
match pkt.get_layer3_pkt() {
|
||||||
|
Ok(Layer3Pkt::IPv4Pkt(ip_pkt)) => {
|
||||||
let Ok(Layer4Pkt::TCP(tcp_pkt)) = ip_pkt.get_layer4_packet() else { continue; };
|
let Ok(Layer4Pkt::TCP(tcp_pkt)) = ip_pkt.get_layer4_packet() else { continue; };
|
||||||
|
|
||||||
|
if !socket_accepts_packet(&socket, &ip_pkt, &tcp_pkt) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let Ok((to_send, received)) = process_packet(&mut socket, tcp_pkt) else { continue; };
|
let Ok((to_send, received)) = process_packet(&mut socket, tcp_pkt) else { continue; };
|
||||||
|
|
||||||
if let Some(received) = received {
|
if let Some(received) = received {
|
||||||
_ = receive_packet.send(received).await;
|
_ = receive_packet.send(received).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
to_send
|
to_send.map(|(b, d)| format_packet!(b.build(srcip, ip, d, None)))
|
||||||
|
},
|
||||||
|
Ok(Layer3Pkt::ARP(arp)) => {
|
||||||
|
if arp.opcode() != 1 || arp.plen() != 4 || arp.hwlen() != 6 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let senderip: [u8; 4] = arp.srcprotoaddr().try_into().unwrap();
|
||||||
|
let sendermac: &[u8] = arp.srchwaddr();
|
||||||
|
let queryip: [u8; 4] = arp.targetprotoaddr().try_into().unwrap();
|
||||||
|
let queryip: Ipv4Addr = queryip.into();
|
||||||
|
|
||||||
|
if queryip != srcip {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = ARPPacket::construct(ARPMode::Reply, ARPProto::IPv4, &src_mac, &sendermac, &queryip.octets(), &senderip);
|
||||||
|
|
||||||
|
Some(EthernetPacket::construct(src_mac, sendermac.try_into().unwrap(), &Layer3Packet::ARP(response)))
|
||||||
|
},
|
||||||
|
_ => continue
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Some(to_send) = send_packet.recv() => {
|
Some(to_send) = send_packet.recv() => {
|
||||||
match send_data(&mut socket, to_send) {
|
match send_data(&mut socket, to_send) {
|
||||||
Ok(v) => Some(v),
|
Ok(v) => v.map(|(b, d)| format_packet!(b.build(srcip, ip, d, None))),
|
||||||
Err(_) => continue
|
Err(_) => continue
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -251,7 +282,6 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let packet = builder.build(srcip, ip, data, None);
|
_ = packets.sendpacket(packet.pkt());
|
||||||
_ = packets.sendpacket(format_packet!(packet).pkt());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user