📚 第一章 网络基础知识
📄 一句话概括

网卡是软件与介质之间的那道门:上面收帧,下面发电平。 衡量网卡能力的不是带宽,是 PPS——因为它按「帧」计费。

📝 本节和前面几节的关系

1.9.1 讲的是「线」,这一节讲「接在线上那块板」。 这一节会算三个数:每秒多少字节、小帧能跑多少 PPS、大帧能跑多少 PPS。

一、网卡做的四件事

一件都不能少:

做的事 具体 不做会怎样
封装/解封装 加帧头、剥帧头 上层拿到的是裸字节
算 CRC 发时算、收时验 坏帧照样上交
持有 MAC 出厂烧在卡里 没法被寻址
DMA 搬运 直接写内存 CPU 被拷贝拖死

第二行那个 CRC 是网卡最有价值的活:它让「坏帧」在进入内存之前就被丢掉, 上层永远看不到损坏的数据。 这也是为什么应用层很少需要自己校验「字节有没有错」——底下已经拦掉了。 第四行那个 DMA 是性能关键:早年的网卡靠 CPU 一个字节一个字节搬, 千兆网卡能把 CPU 占满;有了 DMA,网卡直接把数据写进内存,CPU 只收一个中断。 这就是「网卡也是性能部件」的原因。

二、同样的带宽,帧越小越吃设备

拿一张 144 Mbps 的网卡算三个数:

算法 算式 结果
每秒字节 144 × 10⁶ ÷ 8 18000000
64 字节帧的 PPS 18000000 ÷ 64 281250
1518 字节帧的 PPS 18000000 ÷ 1518 11857

第二行与第三行差了二十多倍: 同样一条 144 Mbps 的链路,全发小帧时每秒要处理 28 万个帧,全发大帧只要 1.2 万个。 而设备处理每个帧的成本是固定的(查表、校验、入队),所以「PPS 打满」比「带宽打满」更容易。 一个 64 字节的帧,真正装数据的只有 46 字节: 64 减 6(目的)减 6(源)减 2(类型)减 4(校验)等于 46。 线上还要再加 12 字节帧间隔与 8 字节前导码,所以小帧在介质上一共占 84 字节。 开销比载荷还大。 这就是「DDoS 用小包打」的原理:同样的带宽,小包能把设备打满而链路还没满。 所以抗攻击不能只看带宽,要看 PPS。

三、网卡也是被攻击面

这一点常被忽略:

攻击点 手法 防护
MAC 泛洪 塞满交换机表 端口安全、MAC 限制
混杂模式 抓别人的包 交换机隔离、加密
唤醒包 远程开机被滥用 关掉 WoL

第一行是针对交换机的:交换机表有容量上限,塞满之后它只能退化成「泛洪」, 于是所有流量都被广播给所有人——这时候攻击者开混杂模式就能抓到别人的包。 所以「MAC 泛洪 + 混杂模式」是一套组合拳。 第二行那个「混杂模式」是抓包工具的默认前提: Wireshark 能抓到别人的包,靠的就是把网卡设成混杂。 但这在交换网络里默认抓不到——除非你做了端口镜像,或者先做 MAC 泛洪。 「交换机网络里抓不到别人的包」这件事,是分层隔离的直接结果。

四、动手 Demo:网卡把「帧」变成「电信号」

列出本机网卡的 MAC、MTU、速率,再拿其中一张算三个数。 重点是那个 PPS,它比带宽更能反映设备压力。

import psutil, _netsim as N

for name, addrs in psutil.net_if_addrs().items():
    mac = [a.address for a in addrs if a.family == psutil.AF_LINK]
    s = psutil.net_if_stats().get(name)
    if mac and s:
        print('%-16s %-20s %-6d %s'
              % (name[:16], mac[0].upper(), s.mtu, s.speed or '—'))

mbps = 144
bps = mbps * 10 ** 6
print()
print('144 Mbps 一秒最多 %d 字节' % (bps // 8))
print('64 字节帧 → %d PPS' % (bps // 8 // 64))
print('1518 字节帧 → %d PPS' % (bps // 8 // 1518))
print('64 字节帧真正装数据 %d 字节' % (64 - 6 - 6 - 2 - 4))

实跑输出:

--------------------------------------------------------------------
网卡把「帧」变成「电信号」
--------------------------------------------------------------------
**网卡是软件与介质之间的那道门**:**上面收到的是帧,下面发出去的是电平。**

  接口             MAC                   MTU      速率Mbps
  ---------------------------------------------------------
  WLAN             9C-B6-D0-0D-D5-0F     1500     144
  以太网           28-F1-0E-18-FA-25     1500     —
  本地连接* 1      9E-B6-D0-0D-D5-0F     1500     —
  本地连接* 2      AE-B6-D0-0D-D5-0F     1500     —
  蓝牙网络连接     9C-B6-D0-0D-D5-10     1500     3

拿其中速率 144 Mbps 的那张来算三个数:

  **一秒最多能发多少字节**:144 × 10⁶ ÷ 8 = 18,000,000 字节
  **最小帧 64 字节时,一秒最多多少帧(PPS)**:281,250 帧
  **最大帧 1518 字节时,一秒多少帧**:11,857 帧

**第二行那个数叫 PPS(每秒包数),是交换机的重要指标**:
**它比「带宽」更能反映设备的处理能力**——
**因为每个帧都要查表、判 CRC、决定往哪送,这些都是按「帧」计费的。**

**一个 64 字节的帧,真正装数据的只有 46 字节**(64 − 6 目的 − 6 源 − 2 类型 − 4 校验 = 46)。
**线上实际还要再加 12 字节帧间隔与 8 字节前导码**,**所以小帧在物理介质上一共占 84 字节。**
**所以小包流量对交换机的压力远大于大包。**

**这也是「DDoS 用小包打」的原因**:**同样的带宽,小包能把设备打满而链路还没满。**

281250 对 11857,差了二十三倍多: 这就是「小包打设备」的算术基础——同样 144 Mbps,全发小帧时每秒要处理 28 万个帧。 64 字节帧的载荷只有 46 字节(64 减 6 减 6 减 2 减 4):开销 18 字节,接近载荷的 40%。 线上再加 12 字节帧间隔与 8 字节前导码,一共占 84 字节。 速率那一列出现「—」的网卡是没插线或没协商成功:它们仍然报 MTU 1500, 因为 MTU 是协议值不是协商结果——这也是「MTU 测不出网卡差异」的原因。

30 秒实验

  1. 把 mbps 改成 1000, 再算一遍 PPS——千兆网卡的 PPS 上限是不是也涨十倍?想想设备的处理能力能不能跟上。
  2. 算一下 128 字节帧的 PPS,和 64 字节的比。
  3. 查一下「巨帧(Jumbo Frame)」为什么能降低 PPS 压力。

常见误区

  1. 以为网卡只管收发、不管校验。 CRC 是网卡算的,坏帧在进内存前就被丢了, 所以应用层很少需要自己验字节。
  2. 以为带宽一样就一样快。 PPS 才是设备处理的瓶颈,同样带宽下小包的帧数是大包的二十多倍。
  3. 以为交换机网络里能随便抓到别人的包。 默认抓不到,要靠端口镜像或 MAC 泛洪才行。
自测三问(点开对答案) 1. 网卡做的四件事是什么? —— **封装/解封装、算 CRC、持有 MAC、DMA 搬运。**CRC 让坏帧在进内存前就被丢掉, DMA 让 CPU 不被拷贝拖死。 2. 为什么说 PPS 比带宽更能反映设备能力? —— **设备处理每个帧的成本是固定的**(查表、校验、入队), 所以同样带宽下小包数量是大包的二十多倍,先把设备打满。 3. 为什么「MAC 泛洪 + 混杂模式」是一套组合拳? —— **泛洪让交换机退化成广播,混杂模式就能收到别人的包。**前提是交换机表被塞满—— 所以防御要做端口安全与 MAC 限制。

下一节讲中继器——它只做一件事:把变弱的信号重新整形。

相关笔记