首页 > 其他分享 >0218-地址解析协议

0218-地址解析协议

时间:2024-08-12 09:30:33浏览次数:10  
标签:arp mut set unwrap 地址 let ethernet 0218 解析

环境

  • Time 2022-11-20
  • VirtualBox 7.0.2
  • Rust 1.65.0
  • pnet 0.31.0
  • CentOS 7

前言

说明

参考:https://docs.rs/pnet_packet/latest/pnet_packet/index.html

目标

使用两台虚拟机,通过 IP 地址,获取到目标主机的 MAC 地址。
日常使用的时候,都是使用 IP 连接服务器,需要使用地址解析协议 ARP 获取 MAC 地址。
IP 地址属于三层协议的内容,所以已经从二层数据链路层进入到了三层网络层。

新增 IP 地址

增加 IP 地址的命令:ip addr add 192.168.44.88/24 dev enp0s8

主机一:

[root@centos7 ~]# hostname
centos7
[root@centos7 ~]# ip addr show enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:16:d2:3f brd ff:ff:ff:ff:ff:ff
    inet 192.168.44.44/24 scope global enp0s8
       valid_lft forever preferred_lft forever

主机二:

[root@centos7-1 ~]# ip addr show enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:36:b1:35 brd ff:ff:ff:ff:ff:ff
    inet 192.168.44.88/24 scope global enp0s8
       valid_lft forever preferred_lft forever
[root@centos7-1 ~]# hostname
centos7-1

可以看到主机一的 IP 是 44,主机二的 IP 是 88。

init_ethernet

fn init_ethernet(interface: &NetworkInterface) -> [u8; 42] {
    // ARP 协议 28 字节,加上数据帧(目的MAC + 源MAC + 类型)14 字节,共 42 字节
    let mut result = [0u8; 42];
    let mut ethernet = MutableEthernetPacket::new(&mut result).unwrap();
    // 地址解析协议还没有目的 MAC,只能发送广播
    ethernet.set_destination(MacAddr::broadcast());
    ethernet.set_source(interface.mac.unwrap());
    // 类型为 ARP,对应数字:0x0806
    ethernet.set_ethertype(EtherTypes::Arp);
    result
}

init_arp

fn init_arp(interface: NetworkInterface) -> [u8; 28] {
    let mut result = [0u8; 28];
    let mut arp = MutableArpPacket::new(&mut result).unwrap();
    let target_ip = "192.168.44.88".parse().unwrap();
    let source_ip = match interface.ips.get(0).unwrap().ip() {
        IpAddr::V4(ip) => ip,
        _ => unreachable!(),
    };
    // 具体参考 RFC 826
    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(target_ip);
    result
}

main

use std::net::IpAddr;

use pnet_datalink::{channel, Channel, MacAddr, NetworkInterface};
use pnet_packet::arp::{ArpHardwareTypes, ArpOperations, ArpPacket, MutableArpPacket};
use pnet_packet::ethernet::{EtherTypes, MutableEthernetPacket};
use pnet_packet::{MutablePacket, Packet};

fn main() {
    let interface = pnet_datalink::interfaces()
        .into_iter()
        .find(|iface| iface.name == "enp0s8")
        .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 ethernet = init_ethernet(&interface);
    let mut arp = init_arp(interface);
    let mut ethernet = MutableEthernetPacket::new(&mut ethernet).unwrap();
    let mut arp = MutableArpPacket::new(&mut arp).unwrap();

    ethernet.set_payload(arp.packet_mut());
    sender.send_to(ethernet.packet(), None).unwrap().unwrap();

    println!("Sent ARP request");
    let buf = reader.next().unwrap();
    let arp = ArpPacket::new(&buf[MutableEthernetPacket::minimum_packet_size()..]).unwrap();
    println!("Target MAC address: {}", arp.get_sender_hw_addr());
}

目的 MAC

Sent ARP request
Target MAC address: 08:00:27:36:b1:35

向目的 IP 地址发送的 ARP 协议,操作系统自动回应。

ARP 缓存

[root@centos7-1 ~]# ip neigh list
192.168.1.144 dev enp0s3 lladdr 08:00:27:93:92:f2 STALE
192.168.1.3 dev enp0s3 lladdr 00:e2:69:5c:cf:b5 DELAY
192.168.44.44 dev enp0s8 lladdr 08:00:27:16:d2:3f STALE
192.168.1.1 dev enp0s3 lladdr d0:60:8c:86:7f:9c STALE
fe80::1 dev enp0s3 lladdr d0:60:8c:86:7f:9c router STALE

可以通过命令 ip neigh list 查看 ARP 缓存。

总结

通过 ARP 协议获取到了目的主机的 MAC 地址。

附录

标签:arp,mut,set,unwrap,地址,let,ethernet,0218,解析
From: https://www.cnblogs.com/jiangbo4444/p/18354339

相关文章

  • 普通人快速上手“低代码平台”?最详细教程地址都在这!
    普通人用好低代码平台,可以从以下几个方面入手:一、明确需求和目标了解应用场景:首先明确你想通过低代码平台解决什么问题,比如是快速搭建一个内部管理系统、客户关系管理系统(CRM)还是其他类型的应用。设定具体目标:设定清晰、可衡量的目标,比如完成应用的搭建时间、预期的用户体验......
  • PrimeFaces SelectOneMenu 与 Ajax 集成实例解析
    ======在现代Web开发中,用户界面的交互性是至关重要的。PrimeFaces作为JavaServerFaces(JSF)的一个流行UI组件库,提供了丰富的组件来增强用户界面。本文将通过一个具体实例,详细介绍如何使用PrimeFaces的SelectOneMenu组件与Ajax技术相结合,实现在选择事件时通过Ajax提交数据。......
  • Java动态代理与方法拦截实战解析
    Java动态代理与方法拦截实战解析在Java编程中,动态代理是一种强大的技术,它允许我们在运行时创建接口的代理实例,并且可以拦截方法调用。本文将通过一个具体的实例,详细解析如何使用JDK的动态代理机制来实现方法拦截,以及如何编写通用的方法拦截器。实现InvocationHandler首先......
  • 深入解析@JsonValue注解在Java序列化中的应用
    深入解析@JsonValue注解在Java序列化中的应用在Java开发中,对象序列化是一个常见的需求,尤其是在进行网络通信或者数据持久化时。Jackson库作为Java领域内一个非常流行的JSON处理库,提供了强大的序列化和反序列化功能。在Jackson2.9版本之后,@JsonValue注解的引入,为开发者提供......
  • Python数据科学的秘密武器:Pandas库的深度解析
    标题:Python数据科学的秘密武器:Pandas库的深度解析Python作为数据科学领域的宠儿,其强大的数据处理能力离不开Pandas库的加持。Pandas是一个开源的数据分析和操作库,它提供了快速、灵活和表达力强的数据结构,旨在使数据清洗和分析工作变得更加简单易行。本文将深入探讨Pandas库......
  • 云中韧性:Spring Cloud服务调用重试机制深度解析
    标题:云中韧性:SpringCloud服务调用重试机制深度解析在微服务架构中,服务间的调用可能会因为网络问题、服务不可达、资源竞争等原因失败。SpringCloud作为微服务架构的主流实现框架,提供了一套完整的服务调用重试机制,以增强系统的健壮性和可靠性。本文将详细探讨SpringCloud......
  • LangChain 安全特性全解析与实践指南
    LangChain安全特性全解析与实践指南引言在人工智能的浪潮中,LangChain以其卓越的能力,成为开发大型语言模型(LLM)应用程序的佼佼者。然而,随着技术的发展,安全问题逐渐浮出水面。本文将深入探讨LangChain的安全特性,并提供详细的代码示例和最佳实践,以确保开发者能够在保障安全......
  • 网络 IP地址 梳理
    IP地址概念分类:A类:000~127,默认子网掩码:255.0.0.0B类:128~191,默认子网掩码:255.255.0.0C类:192~223,默认子网掩码:255.255.255.0D类:224~239E类:240~255A类地址以0开头,第一个字节作为网络号,地址范围为:0.0.0.0~127.255.255.255;B类地址以10开头,前两个字节作为网络号,地址范围是:128.0......
  • 解密AI的未来:决策式AI与生成式AI的深度解析
    在当今科技飞速发展的时代,人工智能(AI)已成为各行各业的热议话题。尤其是决策式AI和生成式AI,这两种技术各具特色,却又相辅相成。本文将深入探讨这两种AI的定义、应用及其未来发展趋势,带你一探究竟!一、什么是决策式AI?决策式AI是指能够通过分析数据和信息,帮助用户做出明智决策的人......
  • 微服务的多面手:Spring Cloud 多数据中心支持全解析
    标题:微服务的多面手:SpringCloud多数据中心支持全解析在微服务架构中,服务的高可用性和弹性伸缩是设计的核心。随着业务的全球化发展,企业经常需要在多个数据中心部署应用以满足不同地区的用户需求,确保服务的快速响应和数据的低延迟访问。SpringCloud作为微服务架构的佼佼......