イーサネットフレームと CRC による誤り検出
なぜ壊れたフレームが確実に弾かれるのかが腑に落ちる。プリアンブルからFCSまでのフレーム構造と、CRC-32の多項式除算による誤り検出の数理・検出能力・限界・ジャンボフレームまで一気に押さえられる。
- 1.イーサネットフレームは プリアンブル/SFD・宛先と送信元MAC・タイプ/長さ・ペイロード・FCS から成り、末尾4バイトのFCSがフレーム全体の誤りを検出する。
- 2.CRC-32は送信データを生成多項式で割った剰余で、受信側は同じ除算で剰余0なら正常と判定する。GF(2)上の多項式除算はXORシフトで実装でき、ハードウェアで高速に計算できる。
- 3.CRC-32は32ビット以下のバーストエラーを必ず検出し、誤り見逃し率は約2のマイナス32乗。ただし誤り訂正はできず、改ざん防止にもならない点が限界。
誤り検出はなぜ必要か
伝送路では電気的ノイズ・クロストーク・減衰によってビットが反転します。1ビットでも化けたフレームを上位層に渡せば、誤ったデータがそのまま処理されてしまう。これを防ぐのがデータリンク層の 誤り検出(error detection) で、イーサネットでは末尾4バイトの FCS(Frame Check Sequence) がその役割を担います。FCSの中身は CRC-32(32ビット巡回冗長検査) で、単純なパリティやチェックサムよりはるかに強力な検出能力を、ハードウェアで安価に実現します。フレーム構造とスイッチングの全体像は /network/ethernet-switching-internals/ を、層構造の位置づけは /network/osi/ を参照してください。
フレーム構造とFCSの位置
L2で運ばれる1単位がフレームです。FCSが「何を対象に計算されるか」を正確に押さえます。
| フィールド | サイズ | FCSの計算対象か |
|---|---|---|
| プリアンブル + SFD | 7 + 1 バイト | 対象外(受信同期用で、本体の前に流れる) |
| 宛先MACアドレス | 6 バイト | 対象 |
| 送信元MACアドレス | 6 バイト | 対象 |
| タイプ/長さ | 2 バイト | 対象 |
| ペイロード(+パディング) | 46〜1500 バイト | 対象 |
| FCS | 4 バイト | この4バイト自体がCRC結果 |
重要なのは、プリアンブルとSFDはCRCの計算対象に含まれない 点です。これらは受信側のクロック同期とフレーム開始位置の検出に使われる「枠外」の信号で、保護対象は宛先MACからペイロード末尾までです。FCSはその範囲を入力としたCRC-32の値を格納し、受信側は同じ範囲を再計算して照合します。
データが46バイトに満たないときはパディングで埋めて最小フレーム長64バイト(ヘッダ18+ペイロード46)を満たします。このパディングもCRCの計算対象に入るため、受信側が長さフィールドから本来のデータ長を切り出してもFCS照合は成立します。最小64バイトの由来はCSMA/CDのスロットタイムで、/network/ethernet-switching-internals/ に詳しいです。
CRCの数理:GF(2)上の多項式除算
CRCの本質は 2を法とする多項式の除算(GF(2)上の除算) です。ビット列を多項式の係数とみなします。たとえばビット列 1101 は次の多項式に対応します。
1·x^3 + 1·x^2 + 0·x^1 + 1·x^0 = x^3 + x^2 + 1
GF(2)では係数が0か1だけで、加算も減算も繰り上がりのない XOR になります(1+1=0)。CRC-32の手順は次の通りです。
1. 送信データの多項式を M(x) とする
2. M(x) を 32ビットぶん左シフト(x^32 を掛ける)= M(x)·x^32
3. それを生成多項式 G(x)(33ビット、最高次 x^32)でGF(2)除算
4. 余り R(x)(32ビット)がCRC値 = FCS
5. 送る列は M(x)·x^32 + R(x) … つまり末尾にFCSを付けた形
ポイントは、M(x)·x^32 + R(x) が G(x)で割り切れる(剰余0) ように設計されている点です。引き算がXORなので、M(x)·x^32 を割った余り R(x) を末尾に足すと、その合成多項式は必ずG(x)の倍数になります。受信側は受け取った列全体をG(x)で割り、余りが0なら誤りなし、0以外なら誤りあり と判定します。FCSを別に取り出して比較する必要すらありません。
イーサネットのCRC-32が使う生成多項式は次の固定値です(IEEE 802.3、最高次から並べた係数の指数)。
G(x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11
+ x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
(32ビット表現で 0x04C11DB7。実装では反転表記 0xEDB88320 も使う)
実際の計算はビット単位のシフトとXORの繰り返しで、CPUを使わずとも論理回路(シフトレジスタ+XORゲート)で1クロックずつ処理できます。これがCRCをハードウェアで高速・安価に実装できる理由です。
// 多項式除算(最上位ビットが1なら G とXOR)の骨子
remainder = 0
各ビット b について:
remainder = (remainder << 1) | b
if remainder の最上位(33ビット目)が 1:
remainder = remainder XOR G
最終 remainder の下位32ビット = CRC
検出能力と限界
CRC-32がパリティより強いのは、どの誤りパターンを必ず検出できるか が数学的に保証されるからです。
| 誤りの種類 | CRC-32の検出能力 |
|---|---|
| 単一ビット誤り | 必ず検出(G(x)が複数項を持つため) |
| 2ビット誤り | フレーム長が一定範囲内なら必ず検出 |
| 奇数個のビット誤り | 原理上は x+1 を因数に持つ多項式なら必ず検出だが、IEEE 802.3 の 0x04C11DB7 は x+1 を因数に持たないため保証されない |
| 32ビット以下のバーストエラー | 必ず検出(剰余の次数が32未満になりえない) |
| 33ビット以上のバースト | ごく低確率で見逃す(約 2^-32) |
最も実用的に効くのが バーストエラー耐性 です。ノイズは連続したビットをまとめて壊す傾向があり、CRC-32は 連続32ビット以下の誤りを100%検出 します。連続長がG(x)の次数(32)以下なら、誤りパターンを表す多項式の次数が32未満となり、33ビットのG(x)では割り切れないからです。33ビットを超えるバーストや無作為な多点誤りでは見逃しが起こりえますが、その確率は約 2^-32(およそ43億分の1)まで抑えられます。なお「CRCは奇数個の誤りを必ず検出する」という説明をよく見かけますが、これは生成多項式が (x + 1) を因数に持つ場合の話です。IEEE 802.3 の CRC-32(0x04C11DB7)は項数が15個(奇数)で (x + 1) を因数に持たないため、奇数個誤りの検出は保証されません。多くの16ビットCRCが (x + 1) を因数に含むのと対照的で、CRC-32の強みはむしろ実用フレーム長における大きなハミング距離とバースト耐性にあります。
CRC-32にできるのは誤りの「検出」だけで、どのビットが化けたかを特定する 誤り訂正はできません。誤りを見つけたフレームはスイッチやNICが黙って破棄し、回復は上位層の再送に委ねられます(TCPの再送は /network/tcp-retransmission/)。さらにCRCは生成多項式が公開された決定的な関数なので、攻撃者がデータを書き換えてFCSも整合するよう再計算すれば検査を通過します。改ざん検知には使えず、完全性保証にはMACやデジタル署名が必要です。
壊れたフレームのたどる末路
受信時にFCS照合が失敗したフレームは破棄され、インターフェースの誤りカウンタが増えます。ここを読むと物理層の不調を切り分けられます。
| カウンタ | 意味 | 主な原因 |
|---|---|---|
| FCS errors / CRC | CRC照合が不一致 | ケーブル不良・ノイズ・コネクタ接触不良 |
| alignment errors | ビット数が8の倍数でない+CRC不一致 | デュプレックス不整合・物理層の問題 |
| runts | 最小64バイト未満の壊れフレーム | 衝突・故障NIC |
| giants / jumbo | MTU超過の過大フレーム | ジャンボ設定不一致・誤設定 |
スイッチの転送方式によってCRCを検証するタイミングが変わる点も実務上重要です。フレーム全体を受け切ってからFCSを検証する ストアアンドフォワード は壊れたフレームを次段に流しませんが、宛先MACだけ読んで即転送する カットスルー はFCS検証前に転送するため、誤りフレームを下流に拡散させえます。tcpdump などでフレームを観察する手法は /network/packet-capture/ を参照してください。
ジャンボフレームとCRCの関係
標準のイーサネットペイロード上限は1500バイトですが、これを超える ジャンボフレーム(一般に最大9000バイト前後のMTU)を使うと、1フレームで運べるデータが増え、フレーム数あたりのヘッダ・FCS・割り込み処理のオーバーヘッドが相対的に下がります。大容量転送やストレージ・仮想化のバックエンドで採用されます。MTUとフラグメンテーションの全体像は /network/mtu/ にあります。
CRC-32の見逃し率 2^-32 は誤りが起きた前提での確率で、フレームが長いほど誤りそのものの発生機会が増えます。9000バイトのジャンボフレームは1500バイトの6倍のビットを1つのCRCで守るため、1フレームあたりの未検出誤り確率が相対的に上昇 します。また経路上の機器でMTU設定が1台でも食い違うと、ジャンボフレームはgiantとして破棄され、大きい転送だけ無言で止まる不具合になります。導入時は経路全体でMTUを揃え、エンドツーエンドの完全性はTCPのチェックサムや上位層に頼る前提で設計します。
「FCSの計算対象は」→ 宛先MACからペイロード末尾まで(プリアンブル/SFDは含まない)。「CRCの数学的本質は」→ GF(2)上の生成多項式による除算で、剰余がFCS。「受信側の判定は」→ 受信列をG(x)で割り、剰余0なら正常。「CRC-32が必ず検出する誤りは」→ 単一ビット誤りと32ビット以下のバースト(奇数個誤りの保証はIEEE 802.3の多項式が x+1 を因数に持たないため成立しない点に注意)。「CRCの限界は」→ 訂正不可・改ざん防止不可。この5点を多項式除算と結びつけられれば上級。
まとめ
イーサネットのFCSは、宛先MACからペイロード末尾までをCRC-32で守る4バイトです。CRCの正体はGF(2)上の多項式除算で、送信側はデータを生成多項式で割った剰余を末尾に付け、受信側は同じ除算の剰余が0かどうかだけで誤りを判定します。XORシフトで構成できるため論理回路で高速に動き、32ビット以下のバーストと奇数個誤りを確実に捕えます。一方で訂正も改ざん検知もできず、ジャンボフレームでは長さに比例して見逃し機会が増える——この「強力だが検出専用」という性質を押さえれば、L2の誤り検出が回路の単純さと数学的保証の両立として読み解けます。
ネットワーク Article
イーサネットフレームと CRC による誤り検出を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
イーサネット
比較で見る軸
難易度: advanced / カテゴリ: ネットワーク / タグ数: 6
導入後に効く点
CRC-32は送信データを生成多項式で割った剰余で、受信側は同じ除算で剰余0なら正常と判定する。GF(2)上の多項式除算はXORシフトで実装でき、ハードウェアで高速に計算できる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- ネットワーク
- タグ数
- 6
判断チェックリスト
- 自社の用途が「イーサネット / CRC」に近いか確認する。
- 強みである「イーサネットフレームは プリアンブル/SFD・宛先と送信元MAC・タイプ/長さ・ペイロード・FCS から成り、末尾4バイトのFCSがフレーム全体の誤りを検出する。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。