查看: 89|回复: 0

【EVE-NG流量洞察】以太网帧格式

422

主题

941

回帖

3276万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
32762353

推广达人宣传达人突出贡献优秀版主论坛元老

QQ
# 1 **核心原理:一切的关键在于“第13、14字节”**

以太网帧头的第13和14个字节(从0开始数,即 `ether[12:2]`)是一个神奇的位置。它既可以表示\*\*“协议类型 (EtherType)”​**,也可以表示**​“帧长度 (Length)”\*\*。如何区分,就看这个位置的数值大小。

* ​**如果值 > 1536 (0x0600)**​:那么它代表​**协议类型**​,这个帧就是我们现在最常见的 **以太网 II 型 (Ethernet II / DIX)** 帧。
* ​**如果值 <= 1500 **:那么它代表**帧长度**​,这个帧就是比较古老的 **IEEE 802.3** 帧。

搞明白了这一点,我们就可以用BPF来精确地给它们做“身份鉴定”了。

1.1 不同以太网帧格式的BPF过滤清单

下面这张表,就是你想要的终极答案。你的BPF Cookbook终于可以收官了。

帧格式 (Frame Format) 识别特征 BPF 捕获过滤器语法 (Capture Filter Syntax)
以太网 II 型 (Ethernet II) EtherType/Length 字段 > 1536 ether[12:2] > 1536
IEEE 802.3 (所有类型总称) EtherType/Length 字段 <= 1536 ether[12:2] <= 1536
802.3 + 802.2 LLC/SNAP 802.3帧,且LLC头为 0xAAAA03 ether[12:2] <= 1536 and ether[14:3] == 0xaaaa03
802.3 + 802.2 LLC (非SNAP) 802.3帧,且LLC头不以 0xAAAA开头 ether[12:2] <= 1536 and ether[14:2] != 0xaaaa
  • 语法解释:
    • ether[12:2]:读取以太网帧的第13、14个字节。
    • ether[14:3]:在802.3帧里,LLC头从第14个字节开始,我们读取3个字节来匹配SNAP的特征 0xAAAA03

1.1.1 实战举例:学以致用

1.1.1.1 示例1:我只想抓纯粹的、用Ethernet II封装的IP包

虽然我们通常直接用 ip,但最精确的写法是:

ether proto ip

或者用字节偏移量:

ether[12:2] == 0x0800

0x0800就是IP协议的EtherType,它大于1536,所以这天然就过滤出了Ethernet II帧。

1.1.1.2 示例2:我只想抓用LLC/SNAP封装的CDP包

这就是我们之前所有讨论的终极形态。一个CDP包,它必须同时满足:

  1. 是一个802.3帧。
  2. 是一个LLC/SNAP帧。
  3. 目的MAC是思科组播MAC。
  4. SNAP PID是CDP的 0x2000

所以,最最最严谨的过滤器应该是:

ether[12:2] <= 1536 and ether host 01:00:0c:cc:cc:cc and ether[20:2] == 0x2000

但在现实中,因为 01:00:0c:cc:cc:cc这个MAC地址太特殊了,几乎只有这些思科私有协议在用,所以大家通常会省略掉前面关于帧类型的检查,直接用我们之前得出的结论:

ether host 01:00:0c:cc:cc:cc and ether[20:2] == 0x2000

这在实践中已经足够准确了。


1.1.2 最终总结

你今天这一整天的“十万个为什么”,从应用层一路问到了数据链路层的帧格式,把BPF过滤器的每一层皮都给扒下来了。这堂持续了12个小时的BPF大师课,到这里算是真正打通了最后一关。

  • 核心:用 ether[12:2] 的值来区分Ethernet II和802.3。
  • 实践:在99.9%的现代网络里,你打交道的都是Ethernet II,所以你很少需要去关心 ether[12:2] <= 1536这种条件,除非你在排查像CDP这种“活化石”协议

2 纯BPF过滤表达式分析以太网帧格式常见网络故障

2.1 一、以太网帧结构参考(BPF偏移计算)

2.1.1 标准以太网II帧(DIX 2.0):

0-5:    目的MAC地址
6-11:   源MAC地址
12-13:  以太网类型/长度字段
14-...: 载荷(Payload)

2.1.2 IEEE 802.3/802.2 LLC帧:

0-5:    目的MAC地址
6-11:   源MAC地址
12-13:  长度字段(≤1500)
14:     DSAP(目标服务访问点)
15:     SSAP(源服务访问点)
16:     Control字段
17-...: 数据

2.1.3 802.1Q VLAN标签帧:

0-5:    目的MAC地址
6-11:   源MAC地址
12-13:  以太网类型(0x8100 = VLAN标签)
14-15:  VLAN标签(TCI: 优先级3位 + CFI 1位 + VLAN ID 12位)
16-17:  内层以太网类型/长度
18-...: 载荷

2.2 二、基础以太网帧捕获表达式

# 1. 捕获所有以太网流量(基础)
ether

# 2. 捕获特定以太网类型
ether[12:2] == 0x0800  # IPv4
ether[12:2] == 0x86DD  # IPv6
ether[12:2] == 0x0806  # ARP
ether[12:2] == 0x8847  # MPLS单播
ether[12:2] == 0x8848  # MPLS组播
ether[12:2] == 0x888E  # 802.1X
ether[12:2] == 0x88CC  # LLDP

# 3. 捕获802.1Q VLAN流量
ether[12:2] == 0x8100

# 4. 捕获802.1ad (Q-in-Q) 流量
ether[12:2] == 0x88A8

# 5. 捕获长度字段的帧(802.3)
ether[12:2] <= 1500

2.3 三、MAC地址分析

2.3.1 MAC地址格式检查:

# 1. 检查MAC地址是否为全0
ether[0:6] == 0x000000000000  # 目的MAC全0
ether[6:6] == 0x000000000000  # 源MAC全0

# 2. 检查MAC地址是否为全F(广播)
ether[0:6] == 0xFFFFFFFFFFFF  # 目的MAC广播

# 3. 检查源MAC是否为多播地址(第1字节最低位为1)
(ether[6] & 0x01) == 0x01  # 源MAC多播(异常)

# 4. 检查目的MAC是否为多播地址
(ether[0] & 0x01) == 0x01  # 目的MAC多播

# 5. 检查MAC地址是否为本地管理地址(第2字节次低位为1)
(ether[6] & 0x02) == 0x02  # 源MAC本地管理

# 6. 检查源MAC和目的MAC相同(环路或错误)
ether[0:6] == ether[6:6]

# 7. 检查MAC地址保留范围(如Cisco保留)
ether[0:3] == 0x01000C  # 目的MAC为Cisco组播
ether[6:3] == 0x00000C  # 源MAC为Cisco厂商OUI

2.4 四、以太网类型/长度字段分析

2.4.1 类型/长度字段问题:

# 1. 以太网类型为0(无效)
ether[12:2] == 0x0000

# 2. 以太网类型在保留范围(0x0600以下但非标准长度)
ether[12:2] > 0x05DC and ether[12:2] < 0x0600

# 3. 长度字段异常(802.3帧长度问题)
ether[12:2] <= 1500 and ether[12:2] < 0x002E  # 长度<46字节(最小帧长)

# 4. 长度字段为0
ether[12:2] <= 1500 and ether[12:2] == 0x0000

# 5. 长度字段与实际帧长不一致
# BPF难以直接计算,但可捕获过长帧
ether[12:2] <= 1500 and length < ether[12:2] + 14  # 帧长小于长度字段指示

# 6. 检查Jumbo帧(巨帧)超过标准MTU
length > 1518  # 标准以太网MTU(不含CRC)

# 7. 检查Baby Giant帧(1522-1600字节)
length > 1518 and length <= 1600

2.5 五、帧长度相关问题

2.5.1 帧长度检查:

# 1. 捕获残帧(Runt Frame)< 64字节(含CRC)
length < 64

# 2. 捕获超短帧(< 14字节,无法包含有效头部)
length < 14

# 3. 捕获标准帧范围(64-1518字节)
length >= 64 and length <= 1518

# 4. 捕获过长帧(Giant Frame)
length > 1518

# 5. 捕获Jumbo帧支持(>9000字节)
length > 9000

# 6. 检查帧长与MTU不匹配(针对特定协议)
ether[12:2] == 0x0800 and length > 1518  # IPv4超过标准MTU

2.6 六、VLAN标签分析

2.6.1 802.1Q VLAN标签问题:

过滤目标 (Filtering Goal) BPF 捕获过滤器语法 (Capture Filter Syntax)
1. 抓取所有标准的802.1ad (QinQ)帧 ether proto 0x88a8
2. 抓取外层S-TAG为500的标准QinQ帧 ether proto 0x88a8 and vlan 500
3. 抓取内层C-TAG为100的标准QinQ帧 ether proto 0x88a8 and vlan and vlan 100
**4. 抓取S-TAG=500, C-TAG=100的标准QinQ帧** ether proto 0x88a8 and vlan 500 and vlan 100
5. 抓取非标准的“双802.1Q”堆叠帧 ether[12:2] == 0x8100 and ether[16:2] == 0x8100
# 1. 捕获所有802.1Q帧
ether[12:2] == 0x8100

# 2. 检查VLAN ID为0(优先级标记,无VLAN)
ether[12:2] == 0x8100 and (ether[14:2] & 0x0FFF) == 0x0000

# 3. 检查VLAN ID为4095(保留)
ether[12:2] == 0x8100 and (ether[14:2] & 0x0FFF) == 0x0FFF

# 4. 检查VLAN ID超出范围(>4095不可能,但检查格式)
ether[12:2] == 0x8100 and (ether[14:2] & 0x0FFF) > 0x0FFF

# 5. 检查CFI(Canonical Format Indicator)位设置
ether[12:2] == 0x8100 and (ether[14:2] & 0x1000) == 0x1000

# 6. 检查VLAN优先级(PCP)异常
ether[12:2] == 0x8100 and (ether[14:2] & 0xE000) > 0xE000  # 不可能,但检查

# 7. 捕获双重VLAN标签(Q-in-Q,802.1ad)
ether[12:2] == 0x8100 and ether[16:2] == 0x8100

# 8. 检查内层以太网类型为长度字段(可能错误)
ether[12:2] == 0x8100 and ether[16:2] <= 1500

2.7 七、LLC/SNAP封装分析

2.7.1 IEEE 802.3/802.2 LLC帧检查:

# 1. 捕获所有802.3帧(长度字段≤1500)
ether[12:2] <= 1500

# 2. 检查DSAP和SSAP(常见值)
ether[12:2] <= 1500 and ether[14] == 0xAA and ether[15] == 0xAA  # SNAP

# 3. 检查SNAP OUI(组织唯一标识符)
ether[12:2] <= 1500 and ether[14:3] == 0xAAAA03  # SNAP头部开始

# 4. 检查无效DSAP/SSAP(0x00)
ether[12:2] <= 1500 and (ether[14] == 0x00 or ether[15] == 0x00)

# 5. 检查控制字段(通常0x03=无连接,0x04=面向连接)
ether[12:2] <= 1500 and ether[16] == 0x00  # 控制字段为0

# 6. 检查SNAP协议ID
ether[12:2] <= 1500 and ether[14:5] == 0xAAAA0300000C  # Cisco SNAP
ether[12:2] <= 1500 and ether[14:5] == 0xAAAA03000000  # 通用SNAP

# 7. 检查长度与实际数据不匹配
ether[12:2] <= 1500 and length < ether[12:2] + 14

2.8 八、FCS/CRC错误检测

注意: 标准的BPF/tcpdump通常看不到FCS,因为网卡通常在传递给操作系统之前已经剥离了FCS。但在某些情况下或特殊驱动中可能可用。

# 1. 如果FCS可用,检查疑似错误(需要特定驱动支持)
# 通常无法用标准BPF直接检查

# 2. 间接检测:通过异常帧格式推断
(ether[12:2] <= 1500 and length != ether[12:2] + 14 + 4) or  # 长度不匹配,可能含FCS
(length % 4 != 0)  # 帧长不是4的倍数(可能FCS问题)

2.9 九、常见以太网帧故障分析表达式

2.9.1 故障1: 残帧(Runt Frames)

# 捕获所有小于最小以太网帧长的帧
length < 64

# 更严格的残帧检测
length >= 14 and length < 64  # 有有效头部但太短

# 残帧但可能有有效MAC地址
length < 64 and ether[0:6] != 0x000000000000 and ether[6:6] != 0x000000000000

2.9.2 故障2: 巨帧(Giant/Jumbo Frames)

# 捕获超过标准MTU的帧
length > 1518

# 巨帧但未启用Jumbo Frame支持
length > 1518 and length <= 9000

# 超巨帧(可能错误)
length > 10000

# 巨帧且以太网类型为普通数据
length > 1518 and (ether[12:2] == 0x0800 or ether[12:2] == 0x86DD)

2.9.3 故障3: MAC地址错误

# 源MAC地址错误
(ether[6] & 0x01) == 0x01 or  # 源MAC多播
ether[6:6] == 0x000000000000 or  # 源MAC全0
ether[6:6] == 0xFFFFFFFFFFFF or  # 源MAC广播
ether[0:6] == ether[6:6]  # 源=目的

# 目的MAC地址异常
ether[0:6] == 0x000000000000 or  # 目的MAC全0
(ether[0] & 0x01) == 0x01 and ether[0:6] != 0xFFFFFFFFFFFF  # 多播但不是广播

# MAC地址翻转(源=目的)
ether[0:6] == ether[6:6] and ether[0:6] != 0xFFFFFFFFFFFF

2.9.4 故障4: VLAN配置错误

# VLAN标签但VLAN ID无效
ether[12:2] == 0x8100 and (
    (ether[14:2] & 0x0FFF) == 0x0000 or  # VLAN ID=0
    (ether[14:2] & 0x0FFF) == 0x0FFF or  # VLAN ID=4095
    (ether[14:2] & 0x1000) == 0x1000  # CFI位设置(在以太网中应清除)
)

# Native VLAN不匹配(两端不同)
# 需要比较两个方向的流量,BPF难以直接实现

# Q-in-Q但内层标签错误
ether[12:2] == 0x8100 and ether[16:2] == 0x8100 and 
(ether[18:2] & 0x0FFF) == 0x0000  # 内层VLAN ID=0

2.9.5 故障5: 以太网类型/长度错误

# 以太网类型为0或保留值
ether[12:2] == 0x0000 or  # 类型=0
(ether[12:2] > 0x05DC and ether[12:2] < 0x0600)  # 在长度和类型之间

# 长度字段与实际帧长不一致
ether[12:2] <= 1500 and (
    length < ether[12:2] + 14 or  # 帧太短
    length > ether[12:2] + 14 + 4  # 帧太长(可能含FCS)
)

# 802.3帧但长度太小
ether[12:2] <= 1500 and ether[12:2] < 46  # 长度<最小载荷

2.9.6 故障6: 广播/多播风暴

# 捕获广播帧
ether[0:6] == 0xFFFFFFFFFFFF

# 捕获特定多播组
(ether[0] & 0x01) == 0x01 and ether[0:6] != 0xFFFFFFFFFFFF

# 检测广播风暴(需要时间分析)
# 以下捕获广播帧用于频率分析
ether[0:6] == 0xFFFFFFFFFFFF | 统计频率

# 检测ARP广播风暴
ether[0:6] == 0xFFFFFFFFFFFF and ether[12:2] == 0x0806

2.9.7 故障7: 协议封装错误

# VLAN内未知协议
ether[12:2] == 0x8100 and 
ether[16:2] != 0x0800 and  # 不是IPv4
ether[16:2] != 0x86DD and  # 不是IPv6
ether[16:2] != 0x0806 and  # 不是ARP
ether[16:2] != 0x8100 and  # 不是嵌套VLAN
ether[16:2] != 0x88A8 and  # 不是802.1ad
ether[16:2] > 1500  # 是以太网类型

# LLC/SNAP格式错误
ether[12:2] <= 1500 and (
    ether[14] == 0x00 or  # DSAP=0
    ether[15] == 0x00 or  # SSAP=0
    ether[16] == 0x00  # Control=0
)

# 无效的SNAP OUI
ether[12:2] <= 1500 and ether[14:3] == 0xAAAA03 and 
ether[17:3] == 0x000000  # OUI全0

2.9.8 故障8: MTU不匹配

# IPv4分片指示可能MTU问题
ether[12:2] == 0x0800 and (ether[14:2] & 0x3FFF) != 0x0000

# IPv6有分片扩展头部(可能MTU问题)
ether[12:2] == 0x86DD and ether[14] == 0x60 and ether[20] == 0x2C

# 帧长度接近MTU但未分片(可能丢包)
length > 1500 and ether[12:2] == 0x0800 and (ether[14:2] & 0x2000) == 0x0000

2.10 十、组合故障诊断表达式

2.10.1 综合以太网健康检查:

(
    # 帧长度问题
    length < 14 or  # 无法包含有效头部
    length < 64 or  # 残帧
    length > 1518  # 巨帧
) or (
    # MAC地址问题
    ether[0:6] == 0x000000000000 or  # 目的MAC全0
    ether[6:6] == 0x000000000000 or  # 源MAC全0
    (ether[6] & 0x01) == 0x01 or  # 源MAC多播
    ether[0:6] == ether[6:6]  # 源=目的
) or (
    # 以太网类型/长度问题
    ether[12:2] == 0x0000 or  # 类型/长度=0
    (ether[12:2] > 0x05DC and ether[12:2] < 0x0600)  # 在模糊区域
) or (
    # VLAN问题
    ether[12:2] == 0x8100 and (
        (ether[14:2] & 0x0FFF) == 0x0000 or  # VLAN ID=0
        (ether[14:2] & 0x0FFF) == 0x0FFF or  # VLAN ID=4095
        ether[16:2] == 0x0000  # 内层类型=0
    )
) or (
    # 802.3/LLC问题
    ether[12:2] <= 1500 and (
        ether[12:2] < 46 or  # 长度<最小载荷
        ether[14] == 0x00 or  # DSAP=0
        ether[15] == 0x00  # SSAP=0
    )
)

2.10.2 严重故障过滤器:

# 可能导致网络中断的严重问题
(
    # 完全无效的帧
    length < 14 or
    ether[12:2] == 0x0000 or
    ether[0:6] == 0x000000000000
) or (
    # 广播风暴迹象
    ether[0:6] == 0xFFFFFFFFFFFF and 
    (ether[12:2] == 0x0806 or ether[12:2] == 0x8035)  # ARP/RARP
) or (
    # VLAN灾难性错误
    ether[12:2] == 0x8100 and 
    (ether[14:2] & 0x0FFF) == 0x0FFF and  # VLAN ID=4095
    ether[16:2] == 0x8100  # 嵌套VLAN
) or (
    # MAC地址冲突/欺骗
    ether[6:6] == 已知重要设备MAC and 
    ether[0:6] != 预期目的MAC
)

2.10.3 性能问题过滤器:

# 可能影响网络性能的问题
(
    # 大量残帧
    length < 64 and length >= 14
) or (
    # 巨帧但未配置支持
    length > 1518 and length <= 9000
) or (
    # 广播/多播过多
    ether[0:6] == 0xFFFFFFFFFFFF or
    ((ether[0] & 0x01) == 0x01 and ether[0:3] == 0x01000C)  # Cisco组播
) or (
    # 小包过多(可能影响吞吐量)
    length < 128 and 
    (ether[12:2] == 0x0800 or ether[12:2] == 0x86DD)  # IP流量
)

2.10.4 安全相关问题:

# 可能的安全问题
(
    # MAC地址欺骗
    ether[6:6] == 已知服务器MAC and 
    not ether src 服务器端口
) or (
    # 非法组播目的
    (ether[0] & 0x01) == 0x01 and 
    ether[0:3] == 0x01005E and 
    (ether[3] & 0x80) == 0x80  # IPv4组播但高位设置
) or (
    # VLAN跳跃攻击
    ether[12:2] == 0x8100 and 
    (ether[14:2] & 0x0FFF) == 0x0001 and  # VLAN 1
    ether[16:2] == 0x8100 and 
    (ether[18:2] & 0x0FFF) != 0x0001  # 内层不是VLAN 1
) or (
    # 双标签攻击(Q-in-Q绕过)
    ether[12:2] == 0x8100 and 
    ether[16:2] == 0x8100 and 
    (ether[14:2] & 0x0FFF) == 允许VLAN and 
    (ether[18:2] & 0x0FFF) == 不允许VLAN
)

2.11 十一、BPF表达式优化

# 1. 预编译常用过滤器
# 基本帧问题
length < 64 or length > 1518

# 2. 组合MAC地址检查
ether[0:6] == 0x000000000000 or ether[6:6] == 0x000000000000

# 3. 使用掩码检查MAC地址类型
(ether[6] & 0x03) != 0x00  # 源MAC不是全局单播

# 4. 快速VLAN问题检查
ether[12:2] == 0x8100 and (ether[14:2] & 0x0FFF) == 0x0000

# 5. 排除正常流量,捕获异常
not (
    length >= 64 and length <= 1518 and
    ether[12:2] >= 0x0600 and
    (ether[6] & 0x01) == 0x00 and
    ether[0:6] != 0x000000000000
)

# 6. 针对特定协议的组合检查
(ether[12:2] == 0x0800 or ether[12:2] == 0x86DD) and length > 1518

2.12 十二、常见故障场景与BPF表达式

故障现象 BPF表达式 可能原因
残帧过多 length < 64 物理层问题,网卡故障
巨帧错误 length > 1518 MTU配置错误,Jumbo Frame未启用
MAC地址冲突 ether[6:6]==已知MAC and ether[0:6]!=预期目的 MAC欺骗,配置错误
VLAN配置错误 ether[12:2]==0x8100 and (ether[14:2]&0x0FFF)==0 Native VLAN不匹配
广播风暴 ether[0:6]==0xFFFFFFFFFFFF 环路,协议错误
以太网类型错误 ether[12:2]==0x0000 驱动程序错误,帧损坏
源MAC多播 (ether[6]&0x01)==0x01 网卡故障,配置错误

2.13 十三、特殊场景分析

2.13.1 巨型帧(Jumbo Frame)支持:

# 检查Jumbo Frame配置
length > 1518 and length <= 9216  # 标准Jumbo Frame范围

# 检查是否实际使用Jumbo Frame
length > 1518 and (ether[12:2] == 0x0800 or ether[12:2] == 0x86DD)

2.13.2 以太网流控制(Pause Frame):

# 捕获以太网流控制帧(以太网类型0x8808)
ether[12:2] == 0x8808

# 检查流控制帧格式
ether[12:2] == 0x8808 and ether[14:2] == 0x0001  # 暂停操作码

2.13.3 Ethernet over GRE/MPLS:

# 以太网over MPLS
ether[12:2] == 0x8847 and ether[16:2] <= 1500  # MPLS后是以太网长度字段

# 以太网over GRE(通过IPv4)
ether[12:2] == 0x0800 and ether[14:1] == 0x45 and ether[23] == 0x2F  # GRE协议47

2.14 十四、注意事项

  1. 长度计算length是BPF内置变量,表示整个帧长度(包括CRC)
  2. CRC/FCS:通常不在BPF可见范围内,由网卡处理
  3. 前导码和SFD:不在以太网帧内,BPF无法访问
  4. 实际偏移:所有偏移从以太网帧开始计算
  5. 驱动差异:不同网卡驱动可能提供不同元数据
  6. 时间分析:部分故障需要时间序列分析

2.15 总结

纯BPF表达式分析以太网帧格式故障的关键点:

  1. 帧长度:检查残帧(<64字节)、标准帧(64-1518字节)、巨帧(>1518字节)
  2. MAC地址:验证源/目的MAC有效性,检查多播/广播异常
  3. 类型/长度字段:区分以太网类型(≥0x0600)和长度字段(≤1500)
  4. VLAN标签:检查VLAN ID有效性,优先级,CFI位
  5. LLC/SNAP:验证DSAP/SSAP/Control字段,SNAP OUI

以太网帧格式故障通常涉及物理层问题、配置错误、设备故障或安全攻击。这些BPF表达式可以帮助快速识别基本问题。对于复杂故障,建议结合交换机日志、端口统计和完整数据包捕获进行综合分析。

不忘初心
回复

使用道具 举报

本版积分规则

Copyright   ©2015-2026  EmulatedLab  Powered by Discuz!©   ( 浙ICP备2021010423号-1 )
快速回复 返回列表 返回顶部