# 1 **BPF 802.1Q VLAN过滤案例实战手册**
## 1.1 **核心原语 (The Primitives)**
* `vlan [vlan_id]`: 匹配VLAN ID为 `[vlan_id]` 的报文。
* `vlan`: 匹配任何带有802.1Q标签的报文。
* `not vlan`: 匹配所有不带802.1Q标签的报文(即Native VLAN流量或来自Access口的流量)。
1.1.1 常见抓包分析场景与过滤语句
| 场景/目标 (Scenario / Goal) |
BPF 捕获过滤器语法 (Capture Filter Syntax) |
“说人话”解释 |
| 1. 抓取特定VLAN的所有流量 |
vlan 100 |
把所有打了VLAN 100标签的包都给我。 |
| 2. 抓取多个VLAN的流量 |
vlan 100 or vlan 200 |
只要是VLAN 100或者VLAN 200的包,我都要。 |
| 3. 抓取特定主机在特定VLAN中的流量 |
vlan 100 and host 192.168.1.10 |
我只想看VLAN 100里,跟192.168.1.10这台主机有关的所有通信。 |
| 4. 抓取两个主机在同一VLAN内的通信 |
vlan 100 and host 192.168.1.10 and host 192.168.1.20 |
我只想看VLAN 100里,主机A和主机B之间的“悄悄话”。 |
| 5. 抓取Trunk链路上的Native VLAN流量 |
not vlan |
在这条Trunk上,所有不带VLAN标签的“裸奔”流量都给我抓出来。 |
| 6. 抓取所有带VLAN标签的流量 |
vlan |
不管是哪个VLAN,只要打了标签,都给我。 |
| 7. 抓取特定VLAN中的特定协议流量 |
vlan 100 and arp |
我只想看VLAN 100里的ARP广播,看看谁在问“谁是XXX”。 |
| 8. 抓取特定VLAN中的OSPF Hello包 |
vlan 100 and ip proto 89 and ip[21] == 1 |
我想看VLAN 100这个广播域里,路由器们是不是在正常地打招呼。 |
| 9. 抓取QinQ报文 (外100, 内20) |
vlan 100 and vlan 20 |
我要抓那种穿着“VLAN 100”外套,里面还穿着“VLAN 20”内衣的套娃包。 |
1.1.2 终极提醒:别再搞混了!
- 位置决定一切:
vlan A and vlan B 匹配的是外层A、内层B。vlan B and vlan A 匹配的是外层B、内层A。顺序绝对重要!
- 这是捕获过滤器:以上所有语法,都用于
tcpdump或EVE-NG Pro这种抓包前的过滤。
- 显示过滤器是另一回事:在Wireshark里分析已抓好的包时,语法要简单得多,比如
vlan.id == 100。
2 纯BPF/libpcap过滤表达式分析802.1Q网络故障
2.1 一、标准BPF原语基础
2.1.1 1. libpcap标准原语
// VLAN相关原语
vlan // 匹配任何单层802.1Q标签
vlan vlan_id // 匹配特定VLAN ID
vlan and ... // 组合过滤
// 层次化原语(自动计算偏移)
vlan // 第一层VLAN标签后的协议头
vlan and ip // VLAN标签后的IP包
vlan and tcp // VLAN标签后的TCP包
vlan and udp // VLAN标签后的UDP包
2.1.2 2. 复合过滤表达式
// 逻辑运算符
and, or, not // 逻辑与、或、非
() // 分组
// 关系运算符
=, !=, >, <, >=, <= // 比较运算
2.2 二、VLAN配置故障检测
2.2.1 1. 标签缺失或错误
// 检测应有VLAN标签但实际缺失
not vlan and (ether dst host 01:80:c2:00:00:00 or ether dst host 01:00:0c:cc:cc:cd)
// 检测Native VLAN数据泄漏
not vlan and (ether[12:2] = 0x0800 or ether[12:2] = 0x0806) and
(ip[16:4] = 255.255.255.255 or ether dst ff:ff:ff:ff:ff:ff)
// 检测VLAN 0(不应出现在生产环境)
vlan 0
// 检测保留VLAN ID 4095
vlan and (ether[14:2] & 0x0fff) = 4095
2.2.2 2. VLAN中继配置问题
// 检测ISL封装中的VLAN问题(Cisco私有)
ether[12:2] = 0x0100 and (ether[16:4] & 0x0fff) > 4094
// 检测DTP协议在带标签帧中
vlan and ether[16:2] = 0x2004
// 检测VTP通告中的VLAN数量异常
vlan and ether[16:2] = 0x2003 and (ether[30:2] > 1000 or ether[30:2] = 0)
2.3 三、QoS/CoS故障检测
2.3.1 1. 优先级标记问题
// 语音流量(VoIP)应有最高优先级(PCP=7)
vlan and (ether[14:1] & 0xe0) != 0xe0 and udp portrange 16384-32767
// 网络控制流量应有高优先级
vlan and (ether[14:1] & 0xe0) = 0x00 and
(ether[16:2] = 0x0800 and (ip[16] = 224.0.0.1 or ip[16] = 224.0.0.2 or ip[16] = 224.0.0.5 or ip[16] = 224.0.0.6))
// 检测DEI标记但不丢弃的流量
vlan and (ether[14:2] & 0x1000) != 0 and (ether[14:1] & 0xe0) = 0x00
2.3.2 2. 应用流量优先级错误
// SSH/SCP应有保证转发(AF)
vlan and tcp port 22 and (ether[14:1] & 0xe0) != 0x60 and (ether[14:1] & 0xe0) != 0x80
// HTTP/S应有尽力而为(BE)
vlan and (tcp port 80 or tcp port 443) and (ether[14:1] & 0xe0) > 0x20
// NTP时间同步应有高优先级
vlan and udp port 123 and (ether[14:1] & 0xe0) != 0xe0
2.4 四、QinQ/802.1ad故障检测
2.4.1 1. 服务提供商QinQ问题
// 检测QinQ帧
ether proto 0x88a8
// 检测S-VLAN标签后的C-VLAN
ether proto 0x88a8 and vlan
// 检测QinQ中的MPLS流量(L2VPN)
ether proto 0x88a8 and ether[18:2] = 0x8847
// 检测QinQ帧长度超限
ether proto 0x88a8 and greater 1522
2.4.2 2. 选择性QinQ配置错误
// 检测应封装但未封装的VLAN
not (ether proto 0x88a8) and vlan 100 and
(ether[16:2] = 0x0800 or ether[16:2] = 0x0806)
// 检测QinQ内层VLAN ID范围错误
ether proto 0x88a8 and (ether[18:2] & 0x0fff) > 100 and (ether[18:2] & 0x0fff) < 200
2.5 五、协议特定故障检测
2.5.1 1. ARP/VLAN问题
// VLAN内ARP请求目标IP在不同子网
vlan and arp and arp[7] = 0x0001 and
((arp[24:4] & 0xffffff00) != (arp[14:4] & 0xffffff00))
// 检测Proxy ARP异常
vlan and arp and arp[7] = 0x0002 and
arp[20:6] = ff:ff:ff:ff:ff:ff
// Gratuitous ARP在错误VLAN
vlan and arp and arp[7] = 0x0001 and
arp[20:4] = arp[30:4] and
(arp[14:4] & 0xffffff00) != (arp[24:4] & 0xffffff00)
2.5.2 2. DHCP与VLAN交互问题
// DHCP Discover带Option 82但中继代理问题
vlan and udp port 67 and
(ether[16:2] = 0x0800 and ip[16:4] = 255.255.255.255)
// 检测DHCP服务器响应中的VLAN不匹配
vlan and udp port 68 and
(udp[8] & 0x80) = 0x00 and
(ether[14:2] & 0x0fff) != (udp[242:2] & 0x0fff)
// BOOTP/DHCP中继代理环路检测
vlan and udp port 67 and
(ip[12:4] = ip[16:4]) // 源IP=目的IP
2.5.3 3. 生成树协议故障
// 检测非VLAN 1的STP BPDU(PVST+)
vlan and (ether[14:2] & 0x0fff) != 1 and
ether[16:2] = 0x010b and ether[18:2] = 0x0000
// 检测MSTP配置不一致
vlan and ether[16:2] = 0x010b and ether[18] = 0x03 and
(ether[14:2] & 0x0fff) = 1 and ether[50] = 0x00
// 检测TCN BPDU在非根VLAN
vlan and ether[16:2] = 0x010b and ether[18] = 0x00 and
ether[25] = 0x80 and (ether[14:2] & 0x0fff) != 0
2.6 六、安全攻击检测
2.6.1 1. VLAN跳跃攻击
// 双重802.1Q封装攻击
vlan and ether[16:2] = 0x8100
// 动态中继协议(DTP)欺骗
vlan and ether[16:2] = 0x2004 and
ether[20:6] != 01:00:0c:cc:cc:cc
// PVLAN违规通信
vlan and (ether[14:2] & 0x0fff) = 100 and
not ether dst 01:80:c2:00:00:00 and
not ether dst 01:00:0c:cc:cc:cd and
(ether dst[0] & 0x01) = 0x00
2.6.2 2. ARP相关攻击
// 跨VLAN ARP欺骗
vlan and arp and arp[7] = 0x0001 and
arp[20:4] = arp[30:4] and
((arp[24:4] & 0xffffff00) != (arp[14:4] & 0xffffff00))
// 路由器ARP缓存投毒
vlan and arp and arp[7] = 0x0002 and
arp[20:4] = <网关IP> and
arp[20:6] != <网关MAC>
2.6.3 3. MAC泛洪/CAM表攻击
// 检测源MAC地址快速变化
vlan and (ether src[0] & 0x01) = 0x00
// 检测未知单播泛洪
vlan and (ether dst[0] & 0x01) = 0x00 and
not ether dst host <已知设备MAC>
// 检测MAC地址翻转攻击
vlan and (ether src = 00:00:00:00:00:01 or
ether src = 00:00:00:00:00:02 or
ether src = 00:00:00:00:00:03)
2.7 七、性能问题检测
2.7.1 1. 广播/多播风暴
// VLAN内广播风暴
vlan and ether dst ff:ff:ff:ff:ff:ff
// IGMP/MLD查询泛滥
vlan and (ether[16:2] = 0x0800 and ip[16] = 224.0.0.1) or
(ether[16:2] = 0x86dd and ip[24] = 0xff02)
// 未知多播泛洪
vlan and (ether dst[0] & 0x01) = 0x01 and
ether dst[1] >= 0x01 and ether dst[1] <= 0x0f
2.7.2 2. MTU/分片问题
// VLAN标签导致帧长度超限
vlan and greater 1518
// IP分片与VLAN组合问题
vlan and ip and (ip[6:2] & 0x2000) != 0
// TCP MSS协商考虑VLAN标签
vlan and tcp and tcp[13] & 0x02 != 0 and
tcp[16:2] > 1460
2.7.3 3. 延迟/抖动问题
// 检测高优先级流量的间隔异常
vlan and (ether[14:1] & 0xe0) = 0xe0 and
udp portrange 16384-32767
// 检测重传与VLAN关系
vlan and tcp and tcp[13] & 0x04 != 0
2.8 八、高级综合诊断
2.8.1 1. 语音/视频VLAN质量
// RTP流在语音VLAN且优先级正确
vlan 100 and (ether[14:1] & 0xe0) = 0xe0 and
udp portrange 16384-32767
// 检测语音包丢失(序列号间隙)
vlan 100 and udp portrange 16384-32767 and
(udp[4:2] - prev_sequence) > 1
// 视频会议流量检测
vlan 200 and (ether[14:1] & 0xe0) >= 0xa0 and
(tcp port 1720 or udp portrange 30000-60000)
2.8.2 2. 数据中心VLAN故障
// 检测FCoE流量VLAN标记
vlan and ether[16:2] = 0x8906 // FCoE
// 检测iSCSI流量优先级
vlan and tcp port 3260 and (ether[14:1] & 0xe0) != 0xa0
// 检测虚拟机迁移流量
vlan and tcp port 8000-8100 and
(ether[16:2] = 0x0800 and ip[9] = 0x06)
2.8.3 3. 无线网络VLAN漫游
// 检测802.1X EAPoL帧的VLAN标记
vlan and ether[16:2] = 0x888e
// 检测CAPWAP隧道中的VLAN
vlan and udp port 5246 and
(ether[16:2] = 0x0800 and ip[9] = 0x11)
// 检测快速漫游时的VLAN切换
vlan and ether[16:2] = 0x888e and
(ether[18] = 0x02 or ether[18] = 0x03) // EAPoL密钥帧
2.9 九、优化性能的BPF技巧
2.9.1 1. 使用协议类型过滤
// 使用标准协议类型而非偏移量
vlan and ip // 而非 vlan and ether[16:2] = 0x0800
vlan and arp // 而非 vlan and ether[16:2] = 0x0806
vlan and tcp // 自动计算TCP在VLAN后的偏移
2.9.2 2. 早期拒绝策略
// 尽早过滤掉不需要的流量
not vlan or (vlan and ...) // 只关注VLAN流量
not ether dst ff:ff:ff:ff:ff:ff // 过滤广播(如果需要)
not ip // 过滤非IP流量
2.9.3 3. 组合过滤条件
// 使用逻辑运算符组合
(vlan 10 or vlan 20) and (tcp port 80 or tcp port 443)
// 使用括号明确优先级
vlan and (ip or arp) and not (udp port 53)
2.9.4 4. 使用BPF原语函数
// 长度检查
greater 1518 // 帧长度大于1518字节
less 64 // 帧长度小于64字节
// 协议类型检查
ether proto 0x8100 // 802.1Q
ether proto 0x88a8 // 802.1ad (QinQ)
ether proto 0x0800 // IPv4
2.10 十、实际应用示例
2.10.1 1. 监控VLAN 10的HTTP问题
vlan 10 and tcp port 80 and
(tcp[13] & 0x08 != 0 or tcp[13] & 0x04 != 0) // PSH或RST标志
2.10.2 2. 检测VLAN间路由故障
(vlan 10 or vlan 20) and
(ip[12:4] & 0xffffff00 = 10.0.10.0 and
ip[16:4] & 0xffffff00 = 10.0.20.0)
2.10.3 3. 语音VLAN质量监控
vlan 100 and udp portrange 16384-32767 and
(greater 200 or less 100) // 包大小异常
这些纯BPF/libpcap过滤表达式可以直接应用于 tcpdump、Wireshark(捕获过滤器)、libpcap/WinPcap编程等场景,无需额外脚本即可实现高效的802.1Q网络故障诊断。