0216-跨网卡通信

环境

  • 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

目标

使用虚拟机,启动 CentOS 系统,然后添加多块网卡进行通信。

查看网卡

[root@centos7 ~]# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:93:92:f2 brd ff:ff:ff:ff:ff:ff
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:16:d2:3f brd ff:ff:ff:ff:ff:ff
4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:de:8a:c8 brd ff:ff:ff:ff:ff:ff

其中的 enp0s8 和 enp0s9 是新增的两块网卡。

reader.rs

use pnet_datalink::{channel, Channel};
fn main() {
    let interface = pnet_datalink::interfaces()
        .into_iter()
        .find(|iface| iface.name == "enp0s9")
        .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"),
    };

    loop {
        let buf = reader.next().unwrap();
        println!("{:?}", buf);
    }
}

sender.rs

use pnet_datalink::{channel, Channel};
use pnet_packet::ethernet::{EtherTypes, MutableEthernetPacket};

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 buffer = [0; 14];
    let mut packet = MutableEthernetPacket::new(&mut buffer).unwrap();

    // 这个是 enp0s9 的 MAC 地址
    let dest = "08:00:27:de:8a:c8".parse().unwrap();
    packet.set_destination(dest);
    packet.set_source(interface.mac.unwrap());
    packet.set_ethertype(EtherTypes::Ipv4);

    sender.send_to(&buffer, None).unwrap().unwrap();
}

enp0s8 的抓包

19:45:54.608688 08:00:27:16:d2:3f > 08:00:27:de:8a:c8, ethertype IPv4 (0x0800), length 14: [|ip]

enp0s9 的抓包

19:45:54.609010 08:00:27:16:d2:3f > 08:00:27:de:8a:c8, ethertype IPv4 (0x0800), length 60: IP0

从这里看,两个包的内容基本一样,跨网卡的时候,数据帧信息的长度从 14 变成了 60。

总结

在数据链路层上,通过 pnet,实现了两块网卡之间的通信,数据链路层的通信只需要 MAC 地址。

附录

posted @   jiangbo4444  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2020-08-12 【JavaScript】Object 构造函数和属性
点击右上角即可分享
微信分享提示