0213-数据链路层协议

环境

  • Time 2022-11-20
  • WSL-Ubuntu 22.04
  • Rust 1.65.0
  • pnet 0.31.0

前言

说明

参考:https://docs.rs/pnet_datalink/0.31.0/pnet_datalink/linux
RFC894:https://www.rfc-editor.org/rfc/pdfrfc/rfc894.txt.pdf
《TCP/IP详解 卷1:协议》:http://www.52im.net/topic-tcpipvol1.html

目标

RFC894 介绍了数据链路层的一些情况。其中以太网帧的前 6 个字节是目的主机的 MAC 地址。
后面跟着的是源主机 MAC 地址,再后面两位是以太网帧的类型,需要使用 0800 标记,表示 IPv4。

接收数据

use pnet_datalink::{linux, Channel};

fn main() {
    let interfaces = linux::interfaces();

    let dummy: Vec<_> = interfaces
        .into_iter()
        .filter(|e| e.name == "mydummy")
        .collect();

    let config = linux::Config::default();
    let channel = linux::channel(&dummy[0], config);
    let (mut _sender, mut reader) = match channel {
        Ok(Channel::Ethernet(tx, rx)) => (tx, rx),
        _ => panic!("Not a valid channel returned"),
    };

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

发送数据

use pnet_datalink::{linux, Channel};

fn main() {
    let interfaces = linux::interfaces();

    let dummy: Vec<_> = interfaces
        .into_iter()
        .filter(|e| e.name == "mydummy")
        .collect();

    let config = linux::Config::default();
    let channel = linux::channel(&dummy[0], config);
    let (mut sender, mut _reader) = match channel {
        Ok(Channel::Ethernet(tx, rx)) => (tx, rx),
        _ => panic!("Not a valid channel returned"),
    };

    let mac = dummy[0].mac.unwrap();
    // 目的 MAC + 源 MAC + 类型 = 14 字节
    let mut buffer = [0; 14];
    buffer[0] = mac.0;
    buffer[1] = mac.1;
    buffer[2] = mac.2;
    buffer[3] = mac.3;
    buffer[4] = mac.4;
    buffer[5] = mac.5;

    // 源
    buffer[6] = mac.0;
    buffer[7] = mac.1;
    buffer[8] = mac.2;
    buffer[9] = mac.3;
    buffer[10] = mac.4;
    buffer[11] = mac.5;

    // 类型
    buffer[12] = 8;
    sender.send_to(&buffer, None).unwrap().unwrap();
}

tcpdump 的显示

21:27:41.811646 36:e0:f1:2a:e8:45 (oui Unknown) > 36:e0:f1:2a:e8:45 (oui Unknown), ethertype IPv4 (0x0800), length 14:  [|ip]

IP 命令显示

其中的 link/ether 表示 MAC 地址,在程序中将其写入到了源和目的地址,tcpdump 也看到了。

8: mydummy: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 36:e0:f1:2a:e8:45 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
             0       0      0       0       0       0
    TX:  bytes packets errors dropped carrier collsns
           756      14      0       0       0       0

总结

了解了数据链路层协议类型,除此之外,还有其它的类型,可以通过给的参考链接查看。

附录

posted @   jiangbo4444  阅读(23)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示