IPv4 / サブネット
32 ビットのアドレス空間を使い切る話と、ヘッダの全フィールド、CIDR / VLSM、サブネット計算、特殊アドレスまで。 IPv4 を「ヘッダの 1 ビットまで読める」レベルに。
IPv4 ヘッダの全フィールド
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL | DSCP |ECN| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| フィールド | サイズ | 意味 |
|---|---|---|
| Version | 4 bit | IP のバージョン。IPv4 = 4 |
| IHL | 4 bit | ヘッダ長(4 バイト単位)。最小 5 = 20 B |
| DSCP | 6 bit | QoS のクラス(旧 TOS フィールド) |
| ECN | 2 bit | 輻輳通知(Explicit Congestion Notification) |
| Total Length | 16 bit | ヘッダ + データの合計バイト数(最大 65,535) |
| Identification | 16 bit | 分割再構成用 ID |
| Flags | 3 bit | R / DF (Don't Fragment) / MF (More Fragments) |
| Fragment Offset | 13 bit | 分割位置(8 バイト単位) |
| TTL | 8 bit | 残ホップ数。0 で破棄 |
| Protocol | 8 bit | 1=ICMP, 6=TCP, 17=UDP, 41=IPv6, 47=GRE, 50=ESP |
| Header Checksum | 16 bit | ヘッダのみのチェックサム |
| Source / Destination | 32 bit × 2 | 送信元 / 宛先 IP |
| Options | 可変 | ほぼ使われない(Record Route / Timestamp 等) |
クラスフルアドレッシング(歴史)
昔は最初の数ビットでクラスを決めていた。今は CIDR で過去の話だが用語だけ残っている。
| クラス | 先頭ビット | 範囲 | デフォルトマスク | 用途 |
|---|---|---|---|---|
| A | 0 | 0.0.0.0 〜 127.255.255.255 | /8 | 大規模 |
| B | 10 | 128.0.0.0 〜 191.255.255.255 | /16 | 中規模 |
| C | 110 | 192.0.0.0 〜 223.255.255.255 | /24 | 小規模 |
| D | 1110 | 224.0.0.0 〜 239.255.255.255 | — | マルチキャスト |
| E | 1111 | 240.0.0.0 〜 255.255.255.255 | — | 予約(実験) |
CIDR(Classless Inter-Domain Routing)
プレフィックス長を /n で表す現代の方式(RFC 4632)。クラス境界に縛られず、任意のビット境界で分割できる。
CIDR の読み方
192.168.10.0/24
└──────────┘└┘
ネットワーク部 (24 bit)
ホスト部 (32 - 24 = 8 bit)
→ ネットワーク数: 1
→ ホスト数: 2^8 - 2 = 254
VLSM(Variable Length Subnet Mask)
1 つの大きな割当を異なる大きさのサブネットに分けて使う技法。クラスフル時代は同一マスク必須だった。
10.0.0.0/16 を分割
├── 10.0.0.0/24 (社員 PC, 254 台)
├── 10.0.1.0/24 (サーバ, 254 台)
├── 10.0.2.0/26 (会議室 Wi-Fi, 62 台)
├── 10.0.2.64/26 (ゲスト Wi-Fi, 62 台)
└── 10.0.3.0/30 (ルータ間 P2P, 2 台)
サブネット計算
マスクから計算するコツ
2 進数で考えるのが一番速い。/24 = 上 24 ビットが 1。
/24 → 11111111.11111111.11111111.00000000 = 255.255.255.0
/26 → 11111111.11111111.11111111.11000000 = 255.255.255.192
/28 → 11111111.11111111.11111111.11110000 = 255.255.255.240
/30 → 11111111.11111111.11111111.11111100 = 255.255.255.252
暗算用の表(最後のオクテット)
| /n | マスク末尾 | ブロックサイズ | ホスト数 |
|---|---|---|---|
| /24 | 0 | 256 | 254 |
| /25 | 128 | 128 | 126 |
| /26 | 192 | 64 | 62 |
| /27 | 224 | 32 | 30 |
| /28 | 240 | 16 | 14 |
| /29 | 248 | 8 | 6 |
| /30 | 252 | 4 | 2 |
| /31 | 254 | 2 | 2 (P2P) |
| /32 | 255 | 1 | 1 |
例: 192.168.1.130/27 が属するサブネット
- /27 のブロックサイズ = 32
- 130 を 32 で割る: 130 ÷ 32 = 4 余り 2 → 4 番目のブロック
- ブロック開始: 32 × 4 = 128
- サブネット: 192.168.1.128/27
- ブロードキャスト: 192.168.1.159
- 有効ホスト範囲: 192.168.1.129 〜 192.168.1.158(30 個)
サブネット内の特殊アドレス
- ネットワークアドレス(最小) — 192.168.1.0(/24 の場合)
- ブロードキャスト(最大) — 192.168.1.255
- 有効ホスト — その間(254 個)
- /31 は例外で 2 アドレスとも使える(P2P 用、RFC 3021)
特殊アドレス一覧
| 範囲 | RFC | 意味 |
|---|---|---|
| 0.0.0.0/8 | 1122 | 「このネットワーク」「未指定」 |
| 10.0.0.0/8 | 1918 | プライベート(大規模) |
| 100.64.0.0/10 | 6598 | キャリアグレード NAT (CGN) |
| 127.0.0.0/8 | 1122 | ループバック (127.0.0.1 = localhost) |
| 169.254.0.0/16 | 3927 | Link-local(DHCP 失敗時) |
| 172.16.0.0/12 | 1918 | プライベート(中規模) |
| 192.0.0.0/24 | 6890 | IETF プロトコル割当 |
| 192.0.2.0/24 | 5737 | ドキュメント用 (TEST-NET-1) |
| 192.88.99.0/24 | 3068 | 6to4 リレー(廃止傾向) |
| 192.168.0.0/16 | 1918 | プライベート(家庭・小規模) |
| 198.18.0.0/15 | 2544 | ベンチマーク用 |
| 198.51.100.0/24 | 5737 | ドキュメント用 (TEST-NET-2) |
| 203.0.113.0/24 | 5737 | ドキュメント用 (TEST-NET-3) |
| 224.0.0.0/4 | 3171 | マルチキャスト |
| 240.0.0.0/4 | 1112 | 予約(実験用) |
| 255.255.255.255/32 | 919 | リミテッド・ブロードキャスト |
ループバック
- 127.0.0.1 = localhost(最も使う)
- 実際は 127.0.0.0/8 全体がループバック扱い(127.1.2.3 でも自分に帰る)
- OS のループバックインタフェース
lo/lo0を経由 - 外には出ない(NIC を経由しない)
ブロードキャスト
3 種類
- 限定ブロードキャスト: 255.255.255.255 — 同一リンク内全員へ。ルータ越えなし
- ディレクト・ブロードキャスト: 192.168.1.255 — 特定サブネットの全員。現代はルータでブロックされる
- サブネット・ブロードキャスト: 自サブネット内宛て
使われ方
- DHCP DISCOVER(IP 取得前にサーバ探し)
- ARP Request
- NetBIOS / mDNS の発見
ブロードキャストドメイン
ブロードキャストが届く範囲。L2 スイッチでは越える、L3 ルータでは止まる。 VLAN で論理分割するとブロードキャストドメインも分かれる。
マルチキャスト
- 224.0.0.0/4 — マルチキャスト範囲
- 224.0.0.1 — 全ホスト(同リンク内)
- 224.0.0.2 — 全ルータ
- 224.0.0.5 / 224.0.0.6 — OSPF
- 224.0.0.9 — RIPv2
- 224.0.0.18 — VRRP
- 224.0.0.251 — mDNS
- 239.0.0.0/8 — 組織内マルチキャスト(プライベート)
- IGMP でグループ参加管理
IPv4 と MAC のマッピング
- IP マルチキャストアドレスから MAC アドレスへの変換規則:
- 01:00:5E:xx:xx:xx の下位 23 ビットに IP の下位 23 ビットをコピー
ARP の詳細
IP → MAC を解決するプロトコル。詳細は 物理・データリンク 参照。 ここでは IPv4 視点での補足。
Gratuitous ARP(無償 ARP)
起動時や IP 変更時に「自 IP の MAC はこれです」と誰も尋ねていないのにブロードキャスト。 ARP テーブルの強制更新、IP 重複検知、HSRP/VRRP のフェイルオーバー通知に使われる。
Proxy ARP
ルータが「他の IP に対して『私が代わりに応答』する」。 サブネットを跨いだ透過接続を実現するが、現代ではあまり使われない。
断片化(Fragmentation)の詳細
なぜ起きるか
経路上の MTU が小さいリンクに大きいパケットが来ると、分割しないと送れない。
分割の仕組み
- 送信元 / 経由ルータが分割
- 各断片に同じ Identification
- Fragment Offset で位置(8 バイト単位)
- MF (More Fragments) flag: 続きあり = 1、最後 = 0
- 受信側で再構成(タイムアウトあり、揃わなければ捨てる)
DF (Don't Fragment) フラグ
立てると経由ルータが分割せずにICMP Fragmentation Needed を返す。 この情報を受けて送信元が MTU を学習する仕組みが PMTUD。 詳細は ICMP ページ。
断片化の問題
- 1 つの断片が落ちると全体が無効
- ルータの処理負荷
- FW が断片を扱いづらい
- 断片化攻撃(teardrop、micro-fragments)
- 現代では「分割されないように送る」が原則。TCP は MSS で調整
MTU と MSS
- MTU: L3 で運べる最大バイト数。Ethernet で 1500
- MSS (Maximum Segment Size): TCP データの最大サイズ。
MSS = MTU - 20 (IP) - 20 (TCP) = 1460 - TCP は SYN 時に MSS をネゴ
- VPN / トンネルで MTU が縮むので調整が必要(例: 1400)
TTL の用途
- 無限ループ防止: ルーティングループに入っても 0 で止まる
- 初期値は OS で異なる: Linux=64, Win=128, 一部=255
- TTL から経由ホップ数がだいたい分かる
- traceroute はこれを 1, 2, 3... と増やして応答を集める
Header Checksum
ヘッダの整合性チェック。各ホップで再計算される(TTL が変わるため)。 IPv6 では削除された(上位層の検査と冗長なため)。
IPv4 アドレス枯渇の現実
- 2011 年に IANA の在庫が枯渇
- 2015 年に各 RIR(地域インターネットレジストリ)でも枯渇
- 中古市場で 1 個 $30〜50 で売買
- クラウド事業者の Elastic IP / Static IP は保持に課金される
- 延命策: NAT、CGN、IPv6 への移行
10 進 / 2 進 / 16 進の変換
IPv4 アドレスは 10 進ドット表記が標準だが、ヘッダや tcpdump では 16 進や 2 進も出てくる。
| 10 進 | 2 進 | 16 進 |
|---|---|---|
| 0 | 00000000 | 00 |
| 128 | 10000000 | 80 |
| 192 | 11000000 | C0 |
| 240 | 11110000 | F0 |
| 255 | 11111111 | FF |
確認コマンド
# Linux のサブネット計算
ipcalc 192.168.1.130/27
sipcalc 192.168.1.0/24
# 手元の IP
ip -4 a
ifconfig | grep "inet "
# サブネットマスクを CIDR で表示
ip route | grep -v default
# ARP テーブル
arp -an
ip neigh
# 重複 IP 検知
arping -c 3 192.168.1.10
Node.js で IPv4 操作
import { isIPv4, isIP } from "node:net"
isIPv4("192.168.1.1") // true
isIP("::1") // 6
isIP("not.an.ip") // 0
// 数値化
function ipToInt(ip: string) {
return ip.split(".").reduce((acc, oct) => (acc << 8) | parseInt(oct), 0) >>> 0
}
ipToInt("192.168.1.1") // 3232235777
よくあるトラブル
| 症状 | 原因 / 対処 |
|---|---|
| IP は取れたが通信不可 | サブネットマスク誤設定 / ゲートウェイ未設定 |
| 同じ LAN なのに繋がらない | マスク違い、別サブネットになっている |
| たまに切れる | IP 重複(DHCP の被り、静的設定ミス) |
| 巨大ファイルで詰まる | MTU / PMTUD 失敗、DF + ICMP ブロック |
| 169.254.x.x が振られる | DHCP に届いていない(APIPA) |
| VPN 後に Web が遅い | MTU 縮小で MSS 調整必要 |
現場では ipcalc で済むが、頭で /26 と聞いて 64 と出るくらいまでは慣れておくと
設計時にスムーズ。基本: ホストビット = 32 - n、ホスト数 = 2^x - 2。