一、以太网协议概述

以太网是一种常用的局域网通信协议,用于在同一网络内的各个节点之间进行通信。以太网的通信方式是通过使用 MAC 地址在网络上进行数据传输。在以太网中,所有节点都能够同时收发数据,因此也称为共享型局域网。

二、以太网报文结构

以太网报文是以太网进行通信的基本单元。以太网报文格式如下:

|  目标 MAC 地址  |   源 MAC 地址   |  类型/长度   |          数据           |   CRC    |
|-----------------|----------------|--------------|------------------------|----------|
|     6 Bytes     |     6 Bytes    |    2 Bytes   |          46~1500       |  4 Bytes |

在解析以太网报文的不同字段时,需要分别对其进行阐述:

1. 目标 MAC 地址

目标 MAC 地址是以太网报文要发送到的设备的 MAC 地址,长度为 6 个字节。在以太网中,使用 MAC 地址进行设备的唯一标识。

1.1 目标 MAC 地址的格式

目标 MAC 地址采用十六进制的方式表示,其中每个字节用“:”隔开。例如,00:0c:29:d6:70:b9。

1.2 目标 MAC 地址的作用

目标 MAC 地址的作用是告诉以太网主机将报文发往哪个设备。当一台设备接收到以太网报文时,会读取该报文中的目标 MAC 地址,如果该地址与自身 MAC 地址相同,则接收报文,否则将报文向网络中传递。

2. 源 MAC 地址

源 MAC 地址是以太网报文发送方的 MAC 地址,长度为 6 个字节。

2.1 源 MAC 地址的格式

源 MAC 地址采用十六进制的方式表示,其中每个字节用“:”隔开。

2.2 源 MAC 地址的作用

源 MAC 地址的作用是告知目标主机,报文的发送方是哪台设备。

3. 类型/长度

类型/长度占 2 个字节,用于指示数据域中所包含的信息类型或数据的长度。

4. 数据

数据域的长度可变,最少为 46 个字节,最大为 1500 个字节。当数据长度不足 46 个字节时,需要通过填充解决,填充中的内容可以是任意数据。

5. CRC

CRC 是校验码,用于检测数据传输是否出错。CRC 的长度为 4 个字节。

三、以太网报文格式的示例代码

以下是以太网报文的示例代码:

#define ETHER_ADDR_LEN  6   /* 以太网地址长度 */
#define ETHER_HDR_LEN   14  /* 以太网报文头部长度 */
#define ETHER_TYPE_IP   0x0800  /* IP 数据报协议类型 */
#define ETHER_TYPE_ARP  0x0806  /* ARP 协议类型 */

/* 以太网报文格式 */
struct ether_header {
    uint8_t eth_dst[ETHER_ADDR_LEN];  /* 目标 MAC 地址 */
    uint8_t eth_src[ETHER_ADDR_LEN];  /* 源 MAC 地址 */
    uint16_t eth_type;                /* 类型/长度 */
}

/* 以太网报文的组装函数 */
void build_ethernet_header(
    struct ether_header *eth_header,
    const uint8_t *dst_addr,
    const uint8_t *src_addr,
    uint16_t ether_type) 
{
    memcpy(eth_header->eth_dst, dst_addr, ETHER_ADDR_LEN);
    memcpy(eth_header->eth_src, src_addr, ETHER_ADDR_LEN);
    eth_header->eth_type = htons(ether_type);
}

四、总结

以太网报文格式是以太网进行通信的基本单元,它由目标 MAC 地址、源 MAC 地址、类型/长度、数据和 CRC 等字段组成。了解以太网报文格式对于理解网络协议栈的运作和实现具有重要意义。