Old-School Networking / 2026 ・ No.03
いにしえのネットワーク入門
第3回 データリンク層 ── MAC アドレスとスイッチ、「全員に尋ねる」ARP
公開
第2回で、ビットが信号になってケーブルを走るところまで見ました。
今回はその1つ上、データリンク層です。フレームの宛名である MAC アドレス、宛名を覚えて配り分けるスイッチ、IP アドレスから MAC アドレスを調べる ARP。
第1回で PC が真っ先に「全員に」尋ねていた理由を、スイッチ1台と PC 3台の練習用ネットワークで確かめます。ループで1つのフレームが毎秒55万個に増える実験もします。
宛名の層
新井第1回で、PC が最初に「10.0.1.1 の MAC は?」って全員に聞いてましたよね。あれ、ちょっと失礼じゃないですか? いきなり全員に。
古井相手の顔を知らないんだから、教室で「古井さんいますか?」と呼ぶしかない。呼ばれた本人だけが手を挙げる。
新井呼ばれてない人には、迷惑ですね。
古井だから、全員に呼びかけるのは最初の1回だけにする工夫がある。今日はそこを見る。
全12回の路線図(いまここ:第3回)
- MAC アドレス ── 6 バイトの中身、会社の番号、ローカルとグローバル、全員あて
- スイッチ ── 宛先を覚えて、必要な口にだけ流す。覚える前は全部の口へ
- ARP ── IP アドレスから MAC アドレスを調べる。答えは30秒ほど覚えておく
- MTU・VLAN・STP ── 1回に運べる大きさ、1台を分ける技、ループを防ぐ技
データリンク層の仕事
データリンク層の仕事は、同じネットワークの中の、となりの機器まで届けることです。第1回で見たとおり、MAC アドレスはルーターを越えるたびに付けかえられました。データリンク層が責任を持つのは「この線の上の、次の1台まで」です。
そのためにデータリンク層は、ビットの並びをフレームという単位に区切り、宛名(宛先と送信元の MAC アドレス)と中身の種類を書き、最後に第2回の FCS を付けて、壊れたものを捨てます。Ethernet(有線)と Wi-Fi(IEEE 802.11)が代表で、どちらも同じ形の MAC アドレスを使います。
データリンク層=となりの機器まで届ける層。宛名は MAC アドレス、単位はフレーム。遠くの相手までの道は、次の第3層(IP)の仕事。
MAC アドレス
MAC アドレスは 6 バイト(48 ビット)の番号で、ふつうは 16 進数を「:」でつないで書きます。前半の 3 バイトは IEEE が会社に割り当てる番号(OUI)、後半の 3 バイトはその会社が機器ごとに付ける番号です。
この連載の PC の MAC アドレス 02:00:00:00:01:10 の中身
先頭のバイトの下の2ビットには意味があります。いちばん下が 1 ならグループあて(マルチキャスト)。全部が 1 の ff:ff:ff:ff:ff:ff は全員あて(ブロードキャスト)です。下から2番目が 1 なら、メーカーが付けた番号ではなく、自分で決めたローカルの番号。この連載の MAC が 02 で始まるのは、読みやすいように手で決めたからです。
Wireshark 4.2.2 に入っている会社の番号の一覧を数えると、3 バイトの OUI は 34,621 個。いちばん多いのは Apple で 1,193 個、次が Cisco の 1,111 個、Huawei の 1,097 個でした。1 つの OUI で約 1,678 万台ぶんの番号が作れるので、大きな会社はいくつも持っています。
ただし最近のスマートフォンや PC は、Wi-Fi では本物の MAC アドレスを使わないことが増えました。iPhone は iOS 14 から「プライベート Wi-Fi アドレス」、Android は 10 から、つなぐネットワークごとにランダムな MAC アドレスを既定で使います。お店の Wi-Fi などで、同じ人の行き来を MAC アドレスで追えないようにするためです。MAC アドレスは「世界で1つの機器の番号」とは限らない、と覚えておきましょう。
フレームの見出し
Ethernet のフレームの見出しは、たった 14 バイトです。
Ethernet の見出し(と、VLAN のタグが入ったとき)
宛先が先頭にあるので、スイッチは最初の 6 バイトを読んだだけで、どの口に出すかを調べ始められます(全部を受け取る前に送り出し始める作りのスイッチもあります)。3つ目の「種類」(EtherType)は、中身が何かを表す 2 バイト。0800 なら IPv4 のパケット、0806 なら ARP です。受け取った側は、この番号を見て中身を次の担当(第3層)に渡します。
スイッチは覚える
第2回で、スイッチは宛先の口にだけ流すと書きました。では、スイッチはどの口にだれがいるかを、どうやって知るのでしょうか。答えは来たフレームの送信元を見て覚えるです。
スイッチの学習。送り主を覚え、知らない宛先は全部の口へ
練習用ネットワークを組み直しました。Linux のブリッジをスイッチにして、新井さん(10.0.1.10)、古井さん(.11)、山田さん(.12)の PC とルーター(.1)をつなぎます。4台すべてで記録しながら、新井さんから古井さんへ ping を3回送りました。
# スイッチ(ブリッジ)が覚えた表。ping の前は空っぽ
$ bridge fdb show br br0
(何もない)
# 新井さんが古井さんに ping したあと(MAC と、その相手がいる口)
$ bridge fdb show br br0
02:00:00:00:01:10 p1
02:00:00:00:01:11 p2
# 覚えた中身は、使われないまま 300 秒たつと忘れる(ageing_time の既定)
| 届いたフレームの数 | 新井 | 古井 | 山田 | ルーター |
|---|---|---|---|---|
| ① ふつうに ping(ARP から) | 8 | 8 | 1 | 1 |
| ② 古井さんの MAC を最初から知っていた場合 | 8 | 8 | 2 | 2 |
①では、山田さんとルーターに届いたのは全員あての ARP の1個だけ。そのあとの ping 6個は、スイッチが覚えた口にだけ流しました。②では、新井さんが ARP をせずにいきなり古井さんあてに送ったので、スイッチはまだ古井さんの口を知らず、ping の1個目を全部の口に流しました(知らない宛先のフレームは全員に配る)。おもしろいのは、そのあと古井さんの PC が新井さんの MAC を知らなかったので、逆向きに ARP の問いを全員に送ったことです。
新井山田さん、②では知らない ping を1つ受け取ってますね。
古井自分あてではないので、山田さんの PC は捨てるだけだ。ただ、同じ LAN の中では、こうして他人のフレームが見えることがある。だから大事な中身は暗号にする(第8回)。
ARP:IP から MAC を引く
アプリが知っているのは相手の IP アドレス(第1回なら 10.0.2.20)です。でもフレームの宛名には MAC アドレスが要ります。そこで登場するのが ARP(Address Resolution Protocol)です。表紙の写真は、新井さんの PC が送った ARP の問いそのものです。
ARP は「全員に尋ねて、本人だけが答える」
問いは全員あて(宛先 ff:ff:ff:ff:ff:ff)で、中には「わたしは 10.0.1.10、02:00:00:00:01:10。10.0.1.11 の MAC を教えて」と書かれています。相手の MAC はまだ分からないので、そこは 0 で埋めてあります。10.0.1.11 の古井さんだけが、新井さんあてに答えます。答えは ARP キャッシュにしばらく覚えておき、次からは尋ねずに済ませます。
# ping の直後の ARP キャッシュ(IP と MAC の対応表)
$ ip neigh show
10.0.1.11 dev eth0 lladdr 02:00:00:00:01:11 REACHABLE
# そのまま待つと……(1秒ごとに見た)
# 32 秒後に STALE(古いかも)に変わった
$ ip neigh show
10.0.1.11 dev eth0 lladdr 02:00:00:00:01:11 STALE
# 30 秒前後(15〜45 秒のどこか)で変わる。消えるわけではない
相手が別のネットワークにいるときは、相手の MAC を尋ねても答えは返ってきません。そこで PC は、出口のルーター(デフォルトゲートウェイ)の MAC を尋ねます。第1回で新井さんの PC が尋ねていたのが 10.0.2.20 ではなく 10.0.1.1 だったのは、このためです。
ARP には「答えが本物か」を確かめるしくみがありません。同じ LAN の悪意ある機械が「10.0.1.1 はわたしです」と嘘の答えを送ると、通信を横取りできてしまいます(ARP スプーフィング)。会社のスイッチには、これを防ぐ機能を持つものもあります。
MTU:1回に運べる大きさ
Ethernet のフレームが運べる中身は、最大 1,500 バイトです。この上限を MTU(Maximum Transmission Unit)と呼びます。見出し 14 と FCS 4 を足すと、フレームは最大 1,518 バイト。第2回の「最低 64 バイト」と合わせて、フレームは 64〜1,518 バイトの間に収まります。
実際に、ちょうど MTU いっぱいの ping と、1 バイトだけ超える ping を送ってみました。
# 中身 1472 バイト+ ICMP 8+ IP 20 = 1500。「分けるな(-M do)」を付けて送る
$ ping -c 1 -M do -s 1472 10.0.1.11
PING 10.0.1.11 (10.0.1.11) 1472(1500) bytes of data.
1480 bytes from 10.0.1.11: icmp_seq=1 ttl=64 time=0.053 ms
# 1 バイト増やして 1501 にすると……
$ ping -c 1 -M do -s 1473 10.0.1.11
PING 10.0.1.11 (10.0.1.11) 1473(1501) bytes of data.
ping: local error: message too long, mtu=1500
1,500 バイトまでは通り、1,501 バイトは送れない
大きなデータは、TCP が MTU に収まるように切り分けて送ります(第6回)。注意したいのは、途中に MTU の小さい区間があるときです。家の光回線の PPPoE(1,492)や VPN のトンネルでは、見出しが増えるぶん MTU が小さくなります。そこで大きなパケットだけが通らなくなると、「小さなページは開くのに、大きなファイルだけ止まる」という不思議な故障になります(第12回で扱います)。
VLAN:1台を分ける
オフィスで「経理の PC と、来客用の Wi-Fi を同じスイッチにつなぎたいけれど、混ぜたくない」というとき、スイッチを何台も買う代わりに VLAN を使います。1台のスイッチの口を、番号ごとに別の LAN として扱う技です。
VLAN 10 と VLAN 20 に分けると、全員あても分かれる
スイッチどうしやルーターへの線では、1本で複数の VLAN を運ぶ(トランク)ために、フレームに 4 バイトのタグを差し込みます。81 00 が「タグがあります」のしるし、続く 12 ビットが VLAN の番号です。
本当は練習用ネットワークでも VLAN を組みたかったのですが、この記事を書いたクラウドの Linux には VLAN の機能が入っておらず、設定できませんでした。そこで写真のフレームは、記録した ARP にタグを手で差し込んで作り、Wireshark に読ませています。
ループと STP
スイッチは「知らない宛先と全員あては、全部の口へ」流します。では、スイッチ2台を2本の線でつないで輪(ループ)を作ると、どうなるでしょう。予備の線のつもりでつなぐと、本当に起きます。測りました。
実測:全員あてを1つ流しただけで
hA から全員あてのフレームを1つだけ送ると、2台のスイッチがそれを互いに流し合い、輪の中を回り続けました。hB には1秒で約 55 万個(3回測って 556,079〜582,306 個)届き、線を1本抜くまで止まりませんでした。フレームには第3層の TTL のような「寿命」がないので、自然には消えないのです。これをブロードキャストストームと呼び、本物のオフィスなら、ネットワークが丸ごと止まります。
それを防ぐのが STP(Spanning Tree Protocol)です。スイッチどうしが連絡を取り合い、輪にならないように、線を1本だけ使わずに止めておきます。
# STP を有効にしたスイッチ2台の、口の状態(収束まで 5.0 秒)
# SW1
pa forwarding
l1 forwarding
l2 forwarding
# SW2:2本目の線(l2)が blocking=止められている
pb forwarding
l1 forwarding
l2 blocking
STP を有効にすると、同じ1つのフレームは hB に1回だけ届きました。さらに、使っている線を切ってみると、止めていた線に切り替わるまで 4.2 秒、ping は 39 回ぶん届きませんでした。これは古い STP(802.1D)の待ち時間を短く設定した場合の値で、既定の設定なら 30 秒ほどかかります。いまの会社のスイッチは、ずっと速く切り替わる RSTP(802.1w)を使うのがふつうです。
新井1つ送っただけで55万個……。予備のつもりで線を足すと、こうなるんですね。
古井いにしえの事務所では、だれかが机の下で余ったケーブルの両端を同じハブに挿して、フロアが止まったものだ。家庭用のスイッチは STP を持たないものも多い。輪は作るな。
自分の PC で確かめる
| 調べたいこと | Mac | Windows | Linux |
|---|---|---|---|
| 自分の MAC アドレス | ifconfig en0 | ipconfig /all | ip link |
| ARP キャッシュ | arp -a | arp -a | ip neigh |
| MTU | ifconfig en0 | netsh interface ipv4 show subinterfaces | ip link |
arp -a を見ると、家のルーター(デフォルトゲートウェイ)の IP アドレスと MAC アドレスが必ず並んでいるはずです。インターネットへ出ていく通信は、すべてここあてのフレームになるからです。
Wi-Fi のアクセスポイントも、データリンク層の機械です。電波の側と有線の側をつなぐ「橋」(ブリッジ)として、MAC アドレスを見て中継します。電波の上のフレーム(802.11)は宛名を最大4つ持つなど形が違いますが、PC の中では Ethernet と同じ形に直されるので、Wireshark でも見た目はほとんど変わりません。
結 — 一枚まとめと、次回
- データリンク層はとなりの機器まで届ける層。宛名は MAC アドレス、単位はフレーム。
- MAC は 6 バイト。前半は会社の番号(OUI)。ff:ff:ff:ff:ff:ff は全員あて。スマホの Wi-Fi はランダムな MAC を使うことが多い。
- 見出しは 14 バイト(宛先・送信元・種類)。種類 0800 は IPv4、0806 は ARP。
- スイッチは送信元を見て覚え、知っている宛先には1つの口だけ、知らない宛先と全員あては全部の口へ。
- ARP は全員に尋ね、本人だけが答える。答えはキャッシュに。実測では 32 秒で STALE に。
- MTU は 1,500。1,472+28 は通り、1 バイト超えると送れない。
- VLAN は1台を分け、4 バイトのタグで区別する。ループは1つのフレームを毎秒55万個にする。STP で1本止める。
新井MAC はとなりまで、ですね。じゃあ、10.0.2.20 みたいな遠くの相手は、だれが道を決めてるんですか?
古井それが次の第3層だ。まずは IP アドレスそのもの。10.0.1.10 の「/24」が何を意味しているか、説明できるか?
参考
- Wikipedia — MAC address
- IEEE Registration Authority (OUI)
- Apple Support — Use private Wi-Fi addresses on Apple devices
- Android Open Source Project — MAC randomization behavior
- RFC 826 — An Ethernet Address Resolution Protocol
- Wikipedia — Maximum transmission unit
- Wikipedia — IEEE 802.1Q (VLAN)
- Wikipedia — Spanning Tree Protocol
- Wikipedia — Broadcast radiation (broadcast storm)
- bridge(8) — Linux manual page
- ip-neighbour(8) — Linux manual page
記録は、筆者がクラウド上の Linux(Ubuntu 24.04)にネットワーク名前空間で作った練習用ネットワークで、2026年10月24日に取ったものです。スイッチは Linux のブリッジ(学習の時間は既定の 300 秒、IGMP の通知は止めた)、ループの実験も Linux のブリッジ2台(STP は 802.1D、forward_delay 2 秒・hello_time 1 秒・max_age 6 秒)で行いました。数字はすべてこの記録と、そのときのコマンドの出力から読んだ実際の値です。VLAN のフレームだけは、この環境で VLAN が使えなかったため、記録した ARP にタグを差し込んで作りました。会社の番号の数は、Wireshark 4.2.2 に入っている一覧(tshark -G manuf)を数えたものです。登場人物は架空の人物です。
いにしえのネットワーク入門 第3回 — データリンク層 / 2026.10