2026年6月16日
2026年6月16日
リンクローカルアドレスの判別方法|169.254.x.x と fe80:: の見分け方と、見つけたときの判断
リンクローカルアドレスは、IPv4 なら 169.254.0.0/16、IPv6 なら fe80::/10 の範囲にあるアドレスで、先頭の数字を見れば判別できます。ただし、同じリンクローカルでも、IPv6 の fe80:: は正常な状態で常にあるもの、IPv4 の 169.254.x.x は多くの場合 DHCP でアドレスを取れなかったサインと、意味が大きく違います。この記事では、OS ごとの確認方法、プログラムでの判別、見つけたときに問題かどうかを判断する手順を説明します。
リンクローカルアドレスとは
リンクローカルアドレスは、同じリンク(ルーターを挟まない同じセグメント)の中だけで有効なアドレスです。ルーターはこの範囲のパケットを転送しないため、インターネットや別のセグメントとの通信には使えません。
- IPv4:169.254.0.0/16。DHCP サーバーから応答が無いときなどに、OS が自動で割り当てます(Windows では APIPA と呼ばれます)。先頭と末尾の 169.254.0.x と 169.254.255.x は予約されていて、通常は割り当てられません。
- IPv6:fe80::/10。実際に使われるのは fe80::/64 の形で、IPv6 が有効なインターフェースには、グローバルアドレスとは別にほぼ常に1つ付いています。
似た範囲との見分け方
判別で迷いやすいのが、プライベートアドレスなど「インターネットに直接出ない」ほかの範囲です。先頭の値で次のように分けられます。
| 範囲 | 種類 | 主な意味 |
|---|---|---|
| 169.254.0.0/16 | IPv4 リンクローカル | 自動割り当て。DHCP 失敗の目印になりやすい |
| 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 | IPv4 プライベート | LAN 内で通常使うアドレス |
| 100.64.0.0/10 | 共有アドレス | 通信事業者の CGNAT などで使われる |
| 127.0.0.0/8、::1 | ループバック | 自分自身 |
| fe80::/10 | IPv6 リンクローカル | 常に付いている。正常 |
| fc00::/7(実際は fd00::/8) | IPv6 ユニークローカル(ULA) | IPv6 のプライベート相当 |
| 2000::/3 | IPv6 グローバル | インターネットで通用するアドレス |
172.16.0.0/12 は 172.16.x.x から 172.31.x.x までなので、172.32.x.x 以降はプライベートではありません。この境界は見間違えやすい点です。
OS ごとの確認方法
Linux
ip コマンドでは、リンクローカルのアドレスに scope link と表示されます。範囲で絞り込むこともできます。
# リンクローカルのアドレスだけを表示
ip -4 addr show scope link
ip -6 addr show scope link
# すべてのアドレスを表示して scope を見比べる
ip addr show
グローバルアドレスは scope global、ループバックは scope host と表示されるので、scope の値を見れば種類が分かります。
Windows
ipconfig /all の出力で、IPv4 のリンクローカルは「自動構成 IPv4 アドレス」、IPv6 のリンクローカルは「リンクローカル IPv6 アドレス」のような項目名で表示されます(表記は Windows のバージョンや言語設定で異なる場合があります)。項目名に頼らず、PowerShell でアドレスの値から絞り込むほうが確実性が高まります。
# 169.254.x.x と fe80:: のアドレスを一覧する
Get-NetIPAddress | Where-Object { $_.IPAddress -like '169.254.*' -or $_.IPAddress -like 'fe80::*' } |
Select-Object InterfaceAlias, IPAddress, PrefixLength
macOS
ifconfig | grep -E 'inet 169\.254\.|inet6 fe80:'
プログラムで判別する
ログの解析やアクセス制御で、受け取ったアドレスがリンクローカルかどうかを判定したい場合は、文字列の先頭一致で自作するより、言語の標準機能を使うほうが安全です。Python なら ipaddress モジュールで判別できます。
import ipaddress
for s in ["169.254.10.20", "192.168.1.5", "fe80::1", "2001:db8::1"]:
ip = ipaddress.ip_address(s)
print(s, "link-local" if ip.is_link_local else "not link-local")
PHP では filter_var() に FILTER_VALIDATE_IP と、予約済み範囲を除外するフラグを組み合わせる方法があります。どの範囲が「予約済み」に含まれるかは PHP のバージョンで変わることがあるため、使う環境の公式マニュアルで確認してください。
サーバー側の注意点として、169.254.169.254 は多くのクラウドでインスタンスのメタデータを返すアドレスとして使われています。WordPress のプラグインやテーマで、利用者が指定した URL にサーバーからアクセスする処理を作る場合は、wp_remote_get() ではなく wp_safe_remote_get() を使い、そのうえで 169.254.0.0/16 を含む内部向けの範囲への接続を拒否するチェックを自分でも入れておくと、意図しない内部アクセスを防ぐ備えになります。
見つけたときの判断
IPv4 の 169.254.x.x が付いている
DHCP でアドレスを取得できなかった可能性が高い状態です。ゲートウェイも DNS も設定されないため、インターネットにはつながりません。次の順に確認します。
- ケーブルの接続や Wi-Fi の接続先が正しいか(リンクが上がっているか)
- DHCP サーバー(家庭ではルーター)が動いているか、同じセグメントの他の機器はアドレスを取れているか
- アドレスの再取得で直るか(Windows は
ipconfig /renew、Linux は使っているネットワーク管理ツールで接続を再起動)
ただし、機器同士を直結した場合や、意図的にリンクローカルで通信する機器(一部のプリンターや組み込み機器)では、169.254.x.x は正常な状態です。また、ルーティングテーブルに 169.254.169.254 への経路があるのは、クラウドのメタデータ用で、問題ではありません。
IPv6 の fe80:: が付いている
正常です。IPv6 では、近隣探索やルーターとのやり取りにリンクローカルアドレスを使うため、グローバルアドレスがあっても fe80:: は残ります。IPv6 の既定の経路の送り先(ゲートウェイ)が fe80:: で始まるのも一般的な形です。問題になるのは「fe80:: しか無く、グローバルアドレスが無い」場合で、このときはルーター広告(RA)や DHCPv6 が届いているかを確認します。
リンクローカルアドレスで通信するときの注意
IPv6 のリンクローカルアドレスは、どのインターフェースでも同じ fe80::/64 の範囲なので、通信するときにはどのインターフェースから出すかを示す「ゾーン ID」が必要です。
# Linux:インターフェース名で指定
ping fe80::1%eth0
# Windows:インターフェース番号で指定(番号は Get-NetIPInterface などで確認)
ping fe80::1%12
ゾーン ID を付けずに実行するとエラーになったり、別のインターフェースから送られたりします。ブラウザーの URL にリンクローカルアドレスを入れる方法は対応状況がまちまちなので、機器の管理画面に入る用途では、グローバルアドレスや IPv4 を使うほうが手間がかかりません(2026年10月現在)。
ネットワーク設定を変更して確認する場合は、変更前の設定を控えておき、遠隔のサーバーでは接続が切れても戻せる手段を確保してから作業してください。
まとめ
- IPv4 は 169.254.0.0/16、IPv6 は fe80::/10 がリンクローカルです。Linux では
scope linkの表示でも判別できます。 - プログラムでは Python の
ipaddressなど標準機能で判別し、文字列の先頭一致の自作は避けます。 - IPv4 の 169.254.x.x は多くの場合 DHCP 失敗のサインで、リンク・DHCP サーバー・再取得の順に確認します。
- IPv6 の fe80:: は常にあるのが正常で、グローバルアドレスが無いときだけ RA や DHCPv6 を調べます。