首页 > 其他分享 >0220-发送 ARP 回应

0220-发送 ARP 回应

时间:2024-08-12 09:27:43浏览次数:20  
标签:ARP arp set mut 0220 44 packet 发送 let

环境

  • 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

相关文章

  • 4.4.Proxy ARP_HSRP_VRRP_GLBP
    交换网络冗余备份ha(高可用性)1容错功能,单点故障2设备冗余,线路冗余,模块冗余。3优化rpr和rpr+rpr切换2-4mrpr+30-60smsfc(多层交换特性卡路由引擎)pfc(交换引擎)rpr+主次引擎都工作,备份主的配置等rpr+1主引擎工作备份也在工作2把runningconif和startupconfig备份3表项......
  • 利用OpenCvSharp进行图像相关操作
    前言程序设计过程,有时也需要对图像进行一些简单操作,C#没有现成的图像处理库,但有人对OpenCV进行了包装,我们可以很方便的使用OpenCvSharp对图像进行操作。当然了,这也需要使用的人员进行一些研究,但相对于C++版本,它已经非常友好了。1、显示图像代码:privatevoidbutton1_Click(......
  • [米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-05 ARP层程序设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑 3.4ARP层该层具有接收ARP请求......
  • C# & Unity 面向对象补全计划 七大原则 之 合成/聚合复用原则( CARP)难度:☆☆☆☆ 总结:
    本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正本系列作为七大原则和设计模式的进阶知识,看不懂没关系请看专栏:http://t.csdnimg.cn/mIitr,查漏补缺1.合成/聚合复用原则(CARP)        合成/聚合复用原则就是在一个新的对象里面使用一些已有的......
  • 0211-使用 dummy 发送数据
    环境Time2022-11-20WSL-Ubuntu22.04Rust1.65.0pnet0.31.0前言说明参考:https://docs.rs/pnet_datalink/0.31.0/pnet_datalink/linux目标前面使用了pnet自己模拟的一个数据链路层的发送和接收过程。现在使用linux的dummy来模拟数据的发送和接收。新建网络接......
  • 使用SixLabors.ImageSharp 进行图片的缩放C#.net core,可跨平台运行
    引用命令空间usingSixLabors.ImageSharp;using SixLabors.ImageSharp.Formats.Png;using SixLabors.ImageSharp.Processing; publicstaticvidResize(byte[]imageBytes,intwidth=400){usingvarsteam=newMemoryStream(imageBytes);using(varimage=......
  • springboot 集成阿里云短信服务,教你轻松实现短信发送功能
    springboot如何发送短信功能在SpringBoot中实现手机号发送短信功能,一般可以通过以下步骤:一、选择短信服务提供商这里使用了阿里云短信服务的SDK来发送短信。阿里云官网:https://www.aliyun.com/1.1开通短信服务进入短信服务控制台,依照如下步骤进行申请1.2新......
  • 发送邮件
    publicvoidSendEmail(){varpath=Path.Combine(Server.MapPath("../"),"Content\\template\\email\\eCalendar.html");vartemplate=System.IO.File.ReadAllText(path);varbody=template.Replace("{{Name}}",......