链路层的分析
Ethernet 协议分析
概述
以太网(Ethernet)是目前局域网中使用最广泛的链路层协议,最初由 Xerox(施乐)和 DEC 公司设计,并通过 DIX 联盟(DEC / Intel / Xerox)命名推广。
由于以太网部署简单、价格低廉,被广泛接受,最终由 IEEE 802.3 委员会将其标准化。
类似的局域网技术还有令牌环网、令牌总线网、FDDI 网等。随着以太网的大力发展,这些标准逐渐被市场抛弃,以太网成为事实上的局域网标准。
帧结构

一个完整的 Ethernet II 帧(含物理层前导部分)由以下字段组成:
| 字段 | 长度 | 作用 |
|---|---|---|
| 前导码(Preamble) | 7 字节 | 10101010 交替序列,用于接收方时钟同步 |
| 帧起始定界符(SFD) | 1 字节 | 10101011,标志帧正式开始 |
| 目标 MAC(Destination MAC) | 6 字节 | 要发给谁 |
| 源 MAC(Source MAC) | 6 字节 | 谁发的 |
| 类型(EtherType) | 2 字节 | 告诉接收者”上层是什么协议”(IPv4 = 0x0800,ARP = 0x0806,IPv6 = 0x86DD) |
| 数据载荷(Payload) | 46 ~ 1500 字节 | 真正要传的内容(IP 包、ARP 包等),不足 46 字节时填充补齐 |
| 帧校验序列(FCS / CRC) | 4 字节 | CRC-32 校验,检测传输错误 |
MTU
以太网的 MTU(最大传输单元)为 1500 字节,即 Payload 的最大长度。上层 IP 包超过 MTU 时需要在网络层分片(见 IP 协议分析一节)。
最小帧长为 64 字节(从目标 MAC 到 FCS),不足时以填充字节补齐——这是早期 CSMA/CD 冲突检测机制的要求。
Wireshark 抓包效果(注意:网卡通常在上交前已剥掉前导码和 FCS,所以抓包里看不到这两个字段):

Ethernet II 与 IEEE 802.3 两种帧格式
以太网实际存在两种帧格式的区别:

- Ethernet II(DIX 帧):第 13~14 字节是 类型(Type) 字段,直接指明上层协议。这是当今互联网上实际使用的帧格式。
- IEEE 802.3 帧:同一位置是 长度(Length) 字段,表示后续数据的长度,上层协议需要靠后面的 LLC/SNAP 子层头部来标识。
区分方法:该 2 字节字段的值若 ≤ 1500(0x05DC)则是长度(802.3 帧);若 ≥ 1536(0x0600)则是类型(Ethernet II 帧)。0x0800、0x0806 等常见 EtherType 都大于 0x0600,因此不会冲突。
网络层
ARP 协议分析
ARP(Address Resolution Protocol,地址解析协议)用于实现 IP 地址到 MAC 地址的映射。
为什么需要 ARP
网络通信中,数据包依据 OSI / TCP-IP 模型自上而下逐层封装后向外发出。在局域网通信中,帧的封装不仅需要源/目 IP 地址,也需要源/目 MAC 地址。而上层应用程序一般只关心 IP 地址,不知道目标的 MAC 地址,因此需要 ARP 协议来动态获取目的主机的 MAC,完成二层封装。
报文结构

| 字段 | 长度 | 含义 | 典型值(以太网 + IPv4) |
|---|---|---|---|
| 硬件类型(Hardware Type) | 2 字节 | 标识链路层协议 | 1 = 以太网 |
| 协议类型(Protocol Type) | 2 字节 | 标识网络层协议 | 0x0800 = IPv4 |
| 硬件地址长度(HLN) | 1 字节 | MAC 地址长度 | 6 |
| 协议地址长度(PLN) | 1 字节 | IP 地址长度 | 4 |
| 操作码(Opcode) | 2 字节 | ARP 数据包类型 | 1 = 请求,2 = 应答 |
| 发送方 MAC | 6 字节 | 发起方的 MAC 地址 | — |
| 发送方 IP | 4 字节 | 发起方的 IP 地址 | — |
| 目标 MAC | 6 字节 | 目标 MAC(请求时填全 0,表示未知待查询) | — |
| 目标 IP | 4 字节 | 要查询的 IP 地址 | — |
ARP 报文总长度固定为 28 字节,直接封装在以太网帧中(EtherType = 0x0806)。
基本 ARP
- 解析方向:已知 IP 未知 MAC
- 触发场景:局域网内同一网段的主机间通信,已知目标 IP,但本地 ARP 缓存表中缺少对应的 MAC 映射。
- 工作流程:
- ARP 请求(Request,
op=1):源主机以以太网广播帧(目的 MAC 为FF:FF:FF:FF:FF:FF)发送请求,询问”谁拥有这个 IP?” - ARP 应答(Reply,
op=2):目标主机发现请求中的目标 IP 是自己后,以单播帧向源主机回复自己的 MAC 地址。 - 缓存更新:源主机收到应答后,将该
IP <-> MAC映射写入本地 ARP 缓存表(默认有老化时间,Windows/Linux 通常为几十秒到几分钟),后续数据帧直接查表封装。
- ARP 请求(Request,
查看本机 ARP 缓存
- Windows:
arp -a- Linux:
ip neigh show
代理 ARP(Proxy ARP)

当局域网内部主机对跨网段目标发起 ARP 请求时,出口路由器/网关设备以自身 MAC 地址应答该请求,这一过程称为代理 ARP。
实现效果:源主机误以为网关的 MAC 就是跨网段目标的 MAC,把后续发往异网段的数据帧全部交给网关,由网关在网络层进行路由转发。该机制常用于屏蔽网络拓扑细节,或在没有正确配置网关的主机上”兜底”实现跨网段通信。
逆向 ARP(InARP)
- 解析方向:已知本地链路标识(DLCI / Hardware ID) 查询对端设备的 IP 地址
- 应用背景:主要应用于帧中继(Frame Relay)或 ATM 等非广播多路访问(NBMA)广域网拓扑中。路由器之间通过逻辑虚电路(PVC,由数据链路连接标识符 DLCI 标记)相连。
- 工作逻辑:
- 路由器明确自身某接口通过特定虚电路(如
DLCI = 100)连通到对端,但不知道对端的 IP 地址。 - 沿该虚电路发送 InARP 请求(
op = 8):“连在 DLCI 100 另一端的设备,你的 IP 是多少?” - 对端路由器以单播回复自身 IP(InARP Reply,
op = 9)。 - 本地路由器自动构建并动态维护
DLCI <-> 对端 IP映射表,用于三层报文的二层虚电路封装。
- 路由器明确自身某接口通过特定虚电路(如
翻转 ARP(RARP)
- 解析方向:已知自身的 MAC 地址 查询分配给自己的 IP 地址
- 应用背景:早期无盘工作站(Diskless Workstation)启动场景。设备没有硬盘,无法保存网络配置,只知道自己固化在网卡 ROM 中的 MAC 地址。
- 工作逻辑:
- 无盘工作站开机时在局域网内广播 RARP 请求:“我的 MAC 是 XX:XX:XX:XX:XX:XX,我的 IP 应该是什么?”
- 局域网中的 RARP 服务器接收请求,查询本地静态配置的
MAC <-> IP数据库。 - 服务器以单播回复对应的 IP 地址。
- 历史现状:RARP 只能分配 IP,无法提供子网掩码、默认网关、DNS 等配置,目前已被 DHCP(BOOTP 的扩展)彻底取代。
免费 ARP(Gratuitous ARP)
一种特殊的 ARP:请求/应答中的发送方 IP 与目标 IP 相同(即”自己问自己的 IP”)。主要用途:
- IP 冲突检测:开机或配置新 IP 时发出,若收到应答说明网内已有人占用该地址。
- 刷新他人 ARP 缓存:主备切换(VRRP/HSRP)、网卡更换后,主动广播新映射,让全网更新 MAC 表。
ARP 的安全问题(攻防视角)
ARP 设计于信任网络的时代,无任何认证机制——任何主机都可以伪造 ARP 应答:
- ARP 欺骗 / ARP 投毒:攻击者持续向受害者发送伪造的 ARP Reply,声称”网关的 IP 对应我的 MAC”,同时向网关投毒反向映射,即可劫持双向流量,实现中间人攻击(MITM)。
- 抓包特征:大量无请求对应的 ARP Reply、同一 IP 对应 MAC 频繁变化、免费 ARP 洪泛。
- 常见工具:
arpspoof(dsniff)、Ettercap、Bettercap。 - 防御:交换机 DAI(动态 ARP 检测)、静态 ARP 绑定、ARP 防火墙。
IP 协议分析
IP(Internet Protocol)是 TCP/IP 协议栈中最核心的协议,提供面向无连接、不可靠的数据报传输服务:
- 无连接:发送前不建立会话,每个包独立选路。
- 不可靠:不保证送达、不保证顺序、不保证不重复;可靠性由上层(TCP)负责。
IP 首部结构

- 版本(Version,4 bit)
标识 IP 版本号,IPv4 中固定为
4。 - 首部长度(IHL,4 bit)
IP 首部长度,单位是 4 字节(32 bit)。无可选项时值为
5,即 20 字节;含选项时最大为15,即 60 字节。 - 区分服务(DS Field / 原 TOS,8 bit) 用于服务质量(QoS)标记。现代用法划分为 DSCP(前 6 bit,流量分类标记) 和 ECN(后 2 bit,显式拥塞通知)。
- 总长度(Total Length,16 bit)
IP 首部 + 数据部分的总字节数,最大 65535 字节。结合 IHL 可算出数据部分长度:
数据长度 = 总长度 - IHL × 4。 - 标识(Identification,16 bit) 用于分片重组。同一个原始 IP 包分出的所有分片具有相同的标识值;不同包之间标识不同(通常逐包递增或随机)。
- 标志(Flags,3 bit) 控制分片行为,每比特含义如下:
| 比特 | 名称 | 含义 |
|---|---|---|
| 0 | Reserved | 保留位,必须为 0 |
| 1 | DF(Don’t Fragment) | 是否禁止分片:0 = 可以分片,1 = 不能分片(路径 MTU 探测依赖此位) |
| 2 | MF(More Fragments) | 是否还有更多分片:0 = 最后一个分片,1 = 后续还有分片 |
- 片偏移(Fragment Offset,13 bit) 标识本分片的数据在原始数据中的位置,单位是 8 字节。接收方据此把分片按序拼回原始数据报。
- 生存时间(TTL,8 bit)
不是时间概念,实际是可经过的路由器跳数。每经过一个路由器减 1,减到 0 则丢弃,并向源端发送 ICMP Time Exceeded 报文——这是
traceroute的实现原理。- 常见初始值:Linux/macOS = 64,Windows = 128,网络设备 = 255。抓包时可据此粗略推断对端操作系统类型(需考虑途中跳数损耗)。
- 协议(Protocol,8 bit)
标识 IP 首部之后承载的上层协议:
1= ICMP,6= TCP,17= UDP。 - 首部校验和(Header Checksum,16 bit) 只校验 IP 首部,不校验数据部分(数据部分由 TCP/UDP 自己的校验和覆盖)。由于 TTL 每跳都会变化,每台路由器转发时都要重新计算此字段。
- 源地址(Source Address,32 bit):发送端 IP。
- 目标地址(Destination Address,32 bit):接收端 IP。
- 可选字段(Options):长度可变,仅在实验或诊断时使用(如记录路由、时间戳),现网中极少使用,很多设备默认丢弃带选项的包。
- 填充(Padding):用 0 把首部补齐到 32 bit 的整数倍。
IP 分片与重组
当 IP 包大于链路 MTU 且 DF=0 时,路由器将其分片:
- 每个分片都是独立的 IP 包:相同的标识、各自的片偏移、除最后一个外 MF=1。
- 中间路由器不重组,只有最终目的主机负责重组;任一分片丢失则整个数据报作废(上层重传)。
- 攻防视角:分片曾被用于绕过 IDS/防火墙检测(分片重叠攻击、Tiny Fragment、Teardrop 等),现代设备会先做虚拟重组再检测。抓包分析时注意用 Wireshark 的重组视图还原原始报文。
传输层
UDP 协议分析
UDP(User Datagram Protocol)是无连接、不可靠的传输层协议,首部仅 8 字节,开销极小:
| 字段 | 长度 | 含义 |
|---|---|---|
| 源端口 | 2 字节 | 发送方端口(可为 0) |
| 目标端口 | 2 字节 | 接收方端口 |
| 长度 | 2 字节 | UDP 首部 + 数据的总长度 |
| 校验和 | 2 字节 | 覆盖伪首部 + UDP 首部 + 数据(IPv4 中可选,常为 0) |
特点与适用场景:不建连、不重传、不排序、无拥塞控制。适用于对时延敏感、可容忍少量丢包的业务:DNS(53)、DHCP(67/68)、实时音视频、游戏等。
TCP 协议分析
TCP(Transmission Control Protocol)提供面向连接、可靠、有序的字节流服务。
TCP 首部结构
| 字段 | 长度 | 含义 |
|---|---|---|
| 源端口 / 目标端口 | 各 2 字节 | 标识两端应用进程 |
| 序列号(Sequence Number) | 4 字节 | 本报文段数据的起始字节序号(SYN 报文中为初始序号 ISN) |
| 确认号(Acknowledgment Number) | 4 字节 | 期望收到的下一个字节序号(ACK 标志有效时才有意义) |
| 数据偏移(Data Offset) | 4 bit | TCP 首部长度,单位 4 字节(最小 5 = 20 字节) |
| 保留 | 3 bit | 置 0 |
| 标志位(Flags) | 9 bit | 见下表 |
| 窗口大小(Window) | 2 字节 | 接收方通告的可接收字节数,用于流量控制 |
| 校验和 | 2 字节 | 覆盖伪首部 + TCP 首部 + 数据 |
| 紧急指针 | 2 字节 | URG=1 时有效,指向紧急数据的末尾 |
| 选项(Options) | 可变 | MSS、窗口扩大因子、SACK、时间戳等 |
标志位(流量分析高频字段):
| 标志 | 含义 | 典型场景 |
|---|---|---|
| SYN | 发起连接 / 序号同步 | 三次握手第 1、2 个包 |
| ACK | 确认号有效 | 握手后几乎所有包都带 ACK |
| FIN | 正常关闭连接 | 四次挥手 |
| RST | 强制重置连接 | 端口关闭时的回应、异常中断 |
| PSH | 催促接收方尽快上交应用层 | 交互式数据 |
| URG | 紧急指针有效 | 极少使用 |
三次握手与四次挥手
sequenceDiagram participant C as 客户端 participant S as 服务端 C->>S: SYN(seq=x) S->>C: SYN+ACK(seq=y, ack=x+1) C->>S: ACK(ack=y+1) Note over C,S: 连接建立 ESTABLISHED C->>S: FIN+ACK S->>C: ACK S->>C: FIN+ACK C->>S: ACK Note over C,S: 连接关闭
- 握手为什么是三次:双方都要确认对方的发送和接收能力正常,并交换初始序列号。两次无法让服务端确认客户端的接收能力。
- 挥手为什么是四次:TCP 全双工,两个方向要分别关闭;服务端收到 FIN 后可能还有数据没发完,故 ACK 与 FIN 分开发送。
TCP 的攻防视角
- 端口扫描识别(nmap 流量特征):
- SYN 扫描(
-sS):只发 SYN,收到 SYN/ACK 判开放(随后回 RST 断连),收到 RST 判关闭。 - FIN/Xmas/Null 扫描:向关闭端口发异常置位包,会收到 RST;开放端口按 RFC 静默丢弃。
- SYN 扫描(
- SYN Flood:大量伪造源 IP 的 SYN 耗尽服务端半连接队列。
- TCP 会话劫持 / RST 注入:在可嗅探或猜解序列号的前提下伪造报文。
附:ICMP 协议分析
ICMP(Internet Control Message Protocol)是网络层的差错与控制报文协议,封装在 IP 中(协议号 1),是 ping 和 traceroute 的基础。
| Type | Code | 含义 |
|---|---|---|
| 8 | 0 | Echo Request(ping 请求) |
| 0 | 0 | Echo Reply(ping 应答) |
| 3 | 0~15 | 目标不可达(Code 细分:1=主机不可达、3=端口不可达、4=需要分片但 DF=1) |
| 11 | 0 | TTL 超时(traceroute 利用此报文逐跳探测路径) |
| 5 | — | 重定向(Redirect) |
攻防视角:
- 主机发现:
ping扫描、nmap -sn。 - 路径探测:
traceroute发送 TTL 递增的 UDP/ICMP 包,靠途中路由器返回的 ICMP 11 报文定位每一跳。 - ICMP 隧道:把数据封装在 Echo 载荷中做隐蔽 C2 通道(如 icmpsh、ptunnel),抓包特征为载荷异常大、内容非 ASCII、单向流量比例失衡。
流量分析实战速查
Wireshark 常用显示过滤器
| 目的 | 过滤器 |
|---|---|
| 只看 ARP | arp |
| 找 ARP 应答(排查欺骗) | arp.opcode == 2 |
| 按 IP 过滤 | ip.addr == 192.168.1.1 |
| 按 MAC 过滤 | eth.addr == aa:bb:cc:dd:ee:ff |
| TCP 握手包 | tcp.flags.syn == 1 && tcp.flags.ack == 0 |
| RST 包(找异常断连 / 扫描) | tcp.flags.reset == 1 |
| 重传包 | tcp.analysis.retransmission |
| ICMP 不可达 / 超时 | icmp.type == 3 || icmp.type == 11 |
| 指定端口 | tcp.port == 80 |
分层分析思路
- 先看二层:源/目 MAC 是否符合预期?有无 ARP 洪泛或异常应答?
- 再看三层:TTL 是否异常(过小可能是伪造源或远端构造)?分片是否正常?
- 后看四层:握手是否完整?RST 出现在什么位置(判断对端拒绝还是中间设备拦截)?重传率如何?
- 最后看载荷:确认协议语义后再下结论,避免被”看起来正常”的包头误导。