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    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      
フィールドサイズ意味
Version4 bitIP のバージョン。IPv4 = 4
IHL4 bitヘッダ長(4 バイト単位)。最小 5 = 20 B
DSCP6 bitQoS のクラス(旧 TOS フィールド)
ECN2 bit輻輳通知(Explicit Congestion Notification)
Total Length16 bitヘッダ + データの合計バイト数(最大 65,535)
Identification16 bit分割再構成用 ID
Flags3 bitR / DF (Don't Fragment) / MF (More Fragments)
Fragment Offset13 bit分割位置(8 バイト単位)
TTL8 bit残ホップ数。0 で破棄
Protocol8 bit1=ICMP, 6=TCP, 17=UDP, 41=IPv6, 47=GRE, 50=ESP
Header Checksum16 bitヘッダのみのチェックサム
Source / Destination32 bit × 2送信元 / 宛先 IP
Options可変ほぼ使われない(Record Route / Timestamp 等)

クラスフルアドレッシング(歴史)

昔は最初の数ビットでクラスを決めていた。今は CIDR で過去の話だが用語だけ残っている。

クラス先頭ビット範囲デフォルトマスク用途
A00.0.0.0 〜 127.255.255.255/8大規模
B10128.0.0.0 〜 191.255.255.255/16中規模
C110192.0.0.0 〜 223.255.255.255/24小規模
D1110224.0.0.0 〜 239.255.255.255マルチキャスト
E1111240.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マスク末尾ブロックサイズホスト数
/240256254
/25128128126
/261926462
/272243230
/282401614
/2924886
/3025242
/3125422 (P2P)
/3225511

例: 192.168.1.130/27 が属するサブネット

  1. /27 のブロックサイズ = 32
  2. 130 を 32 で割る: 130 ÷ 32 = 4 余り 2 → 4 番目のブロック
  3. ブロック開始: 32 × 4 = 128
  4. サブネット: 192.168.1.128/27
  5. ブロードキャスト: 192.168.1.159
  6. 有効ホスト範囲: 192.168.1.129 〜 192.168.1.158(30 個)

サブネット内の特殊アドレス

特殊アドレス一覧

範囲RFC意味
0.0.0.0/81122「このネットワーク」「未指定」
10.0.0.0/81918プライベート(大規模)
100.64.0.0/106598キャリアグレード NAT (CGN)
127.0.0.0/81122ループバック (127.0.0.1 = localhost)
169.254.0.0/163927Link-local(DHCP 失敗時)
172.16.0.0/121918プライベート(中規模)
192.0.0.0/246890IETF プロトコル割当
192.0.2.0/245737ドキュメント用 (TEST-NET-1)
192.88.99.0/2430686to4 リレー(廃止傾向)
192.168.0.0/161918プライベート(家庭・小規模)
198.18.0.0/152544ベンチマーク用
198.51.100.0/245737ドキュメント用 (TEST-NET-2)
203.0.113.0/245737ドキュメント用 (TEST-NET-3)
224.0.0.0/43171マルチキャスト
240.0.0.0/41112予約(実験用)
255.255.255.255/32919リミテッド・ブロードキャスト

ループバック

ブロードキャスト

3 種類

使われ方

ブロードキャストドメイン

ブロードキャストが届く範囲。L2 スイッチでは越える、L3 ルータでは止まる。 VLAN で論理分割するとブロードキャストドメインも分かれる。

マルチキャスト

IPv4 と MAC のマッピング

ARP の詳細

IP → MAC を解決するプロトコル。詳細は 物理・データリンク 参照。 ここでは IPv4 視点での補足。

Gratuitous ARP(無償 ARP)

起動時や IP 変更時に「自 IP の MAC はこれです」と誰も尋ねていないのにブロードキャスト。 ARP テーブルの強制更新、IP 重複検知、HSRP/VRRP のフェイルオーバー通知に使われる。

Proxy ARP

ルータが「他の IP に対して『私が代わりに応答』する」。 サブネットを跨いだ透過接続を実現するが、現代ではあまり使われない。

断片化(Fragmentation)の詳細

なぜ起きるか

経路上の MTU が小さいリンクに大きいパケットが来ると、分割しないと送れない

分割の仕組み

DF (Don't Fragment) フラグ

立てると経由ルータが分割せずにICMP Fragmentation Needed を返す。 この情報を受けて送信元が MTU を学習する仕組みが PMTUD。 詳細は ICMP ページ。

断片化の問題

MTU と MSS

TTL の用途

Header Checksum

ヘッダの整合性チェック。各ホップで再計算される(TTL が変わるため)。 IPv6 では削除された(上位層の検査と冗長なため)。

IPv4 アドレス枯渇の現実

10 進 / 2 進 / 16 進の変換

IPv4 アドレスは 10 進ドット表記が標準だが、ヘッダや tcpdump では 16 進や 2 進も出てくる。

10 進2 進16 進
00000000000
1281000000080
19211000000C0
24011110000F0
25511111111FF

確認コマンド

# 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。