Old-School Networking / 2026 ・ No.04
いにしえのネットワーク入門
第4回 IP アドレス ── 32 ビットの住所と「/24」、DHCP、そして IPv6
公開
第3回の MAC アドレスは「となりまで」の宛名でした。今回から第3層、ネットワーク層に入ります。
前半は IP アドレスそのものです。10.0.1.10 は何ビットで、「/24」は何を表すのか。マスクを1つ取り違えると何が起きるのかを、実際に間違えて確かめます。
後半は、住所をもらうしくみ(DHCP)、住所が足りなくなった話、そして IPv6。ルーターの道案内は次回です。
住所の層
新井「/24」の意味、宿題でしたよね。調べました! ……サブネットマスク、の、なにか、です。
古井半分は合っている。では、それを /16 と書き間違えたら、申請はどうなる?
新井えっ、ちょっと広くなるだけで、届くんじゃないですか?
古井試そう。間違えるなら、練習用のネットワークで間違えるのがいちばん安い。
全12回の路線図(いまここ:第4回)
- IP アドレスの中身 ── 32 ビット、ネットワークの番号と機械の番号、/24 とマスク
- 送る前の判断 ── 相手は同じネットワークか。間違えると何が起きるか(実測)
- 特別な住所と DHCP ── プライベート、127、169.254。住所をもらうまでの4往復(実測)
- 住所の枯渇と IPv6 ── 2011年に在庫が尽きた話と、128 ビットの住所
IP アドレスは 32 ビット
第3回の MAC アドレスは「となりの機器まで」の宛名で、ルーターを越えるたびに付けかえられました。それに対して IP アドレスは、最後の相手までの住所で、途中で変わりません。
IPv4 の住所は 32 ビット(4 バイト)です。8 ビットずつ4つに区切り、それぞれを 0〜255 の 10 進数にして「.」でつないだのが、おなじみの 10.0.1.10 という書き方です。
10.0.1.10 は、32 個の 0 と 1
住所は2つの部分に分かれています。前はネットワークの番号(どの町か)、後ろは機械の番号(何番地か)。どこで区切るかを表すのが「/24」の数字で、前から 24 ビットがネットワークの番号という意味です。
# 第1回の PC の住所
$ ip -4 addr show eth0
inet 10.0.1.10/24 scope global eth0
# 2進数にすると(/24=前から24ビットがネットワークの番号、残り8ビットが機械の番号)
address 00001010.00000000.00000001.00001010 10.0.1.10
mask 11111111.11111111.11111111.00000000 255.255.255.0
# 住所とマスクの AND(両方 1 のところだけ 1)=ネットワークの番号
network 00001010.00000000.00000001.00000000 10.0.1.0
「/」の数字とマスク
/24 は、「前から 24 個が 1、残りが 0」の 32 ビットのマスクと同じことを表します。10 進数で書けば 255.255.255.0。昔はこのマスクの形で書くのがふつうでしたが、いまは短い「/24」(CIDR 表記)がよく使われます。
「/」の数字が大きいほど、ネットワークは小さい
/24 のネットワークには 256 個の住所がありますが、機械に付けられるのは 254 個です。いちばん最初(10.0.1.0)はネットワークそのものを指す番号、いちばん最後(10.0.1.255)はそのネットワークの全員あての番号として取ってあるからです。/30 なら 4 個のうち 2 個、ルーターどうしを1本でつなぐときによく使います。
「/24」=前から 24 ビットがネットワークの番号=マスク 255.255.255.0。数字が 1 増えるごとに、ネットワークの大きさは半分になる。
同じネットワークか、よそか
/24 が本当に効いてくるのは、送る前の判断です。PC はパケットを送る前に、相手の住所と自分の住所を、自分のマスクで切って比べます。同じなら相手は同じネットワークにいるので、相手の MAC を ARP で尋ねて直接送ります。違えばよそなので、ルーター(デフォルトゲートウェイ)に渡します。
送る前の分かれ道
では冒頭の問い。第1回の練習用ネットワークで、新井さんの PC の住所を正しい 10.0.1.10/24 と、間違えた 10.0.1.10/16 にして、ルーターの向こうのサーバー(10.0.2.20)へ ping を送りました。
# 正しく /24:10.0.2.20 は「よそ」なので、ルーター(10.0.1.1)経由で出す
$ ip addr add 10.0.1.10/24 dev eth0
$ ip route get 10.0.2.20
10.0.2.20 via 10.0.1.1 dev eth0 src 10.0.1.10 uid 0
$ ping -c 3 10.0.2.20
3 packets transmitted, 3 received, 0% packet loss
# 間違えて /16:10.0.2.20 も「同じネットワーク」と判断し、ルーターを通さず直接送ろうとする
$ ip addr add 10.0.1.10/16 dev eth0
$ ip route get 10.0.2.20
10.0.2.20 dev eth0 src 10.0.1.10 uid 0
$ ping -c 3 10.0.2.20
3 packets transmitted, 0 received, 100% packet loss
/16 にすると、PC は 10.0.2.20 を「同じネットワーク」と判断し、ルーターを通さずに直接送ろうとして、その MAC を全員に尋ねました。でもサーバーはルーターの向こうにいるので、だれも答えません。3回尋ねたところで、ping は1つも出ていけませんでした(100% 失敗)。マスクは「ちょっと広い・狭い」ではなく、道の選び方そのものを変えてしまうのです。
新井広くしたら届かなくなるなんて……。
古井「隣町の人も同じ町内だ」と思いこんで、玄関先で大声で呼び続けているようなものだ。郵便局に頼めば届くのに。
特別な住所
IPv4 の住所の中には、特別な役目のために取ってあるものがあります。最初の1バイトの数直線に並べると、こうなります。
特別な意味を持つ住所
いちばん大事なのはプライベートアドレス(10.0.0.0/8・172.16.0.0/12・192.168.0.0/16)です。家や会社の中なら、だれに断ることもなく自由に使えます。そのかわり、インターネットの上ではそのまま使えません。この連載の 10.0.1.10 もプライベートです。家のルーターが、外に出るときに自分のグローバルな住所に付けかえて(NAT)、たくさんの機械を1つの住所の後ろに隠しています(第5回)。
127 で始まる住所は自分自身です。127.0.0.1 が有名ですが、/8 なので 127 で始まれば何でも自分です。
# 127 で始まる住所は、すべて「自分自身」
$ ping -c 1 127.42.42.42
64 bytes from 127.42.42.42: icmp_seq=1 ttl=64 time=0.285 ms
$ ip addr show lo
inet 127.0.0.1/8 scope host lo
169.254 で始まる住所が自分の PC に付いていたら、DHCP から住所をもらえなかったしるしです(次の章)。100.64.0.0/10 は、回線事業者が加入者の間で共有するための住所で、Tailscale の記事で見た 100.x.y.z もこの範囲を使っています。
DHCP:住所をもらう
家の Wi-Fi につないだだけで、PC には住所が付きます。配っているのは、ルーターの中の DHCP サーバーです。練習用ネットワークのルーターに DHCP を足し、住所を持たない PC で住所をもらうところを記録しました(表紙の写真)。
# 住所を持たない PC で dhclient を動かした記録(住所は DHCP でもらう)
$ dhclient -v eth0
DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3 (xid=0xcc0bcf66)
DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 5 (xid=0xcc0bcf66)
DHCPOFFER of 10.0.1.177 from 10.0.1.1
DHCPREQUEST for 10.0.1.177 on eth0 to 255.255.255.255 port 67 (xid=0x66cf0bcc)
DHCPACK of 10.0.1.177 from 10.0.1.1 (xid=0xcc0bcf66)
bound to 10.0.1.177 -- renewal in 1714 seconds.
# もらった ACK に書かれていたもの(Wireshark の明細から)
Your (client) IP address: 10.0.1.177
Subnet Mask: 255.255.255.0
Router: 10.0.1.1
Domain Name Server: 10.0.1.1
IP Address Lease Time: 1 hour (3600)
Renewal Time Value: 30 minutes (1800)
実測:住所が決まるまでの4往復(と待ち時間)
やりとりは「Discover(ください)→ Offer(これはどう?)→ Request(それをください)→ ACK(どうぞ)」の4つです。住所がない PC は自分の住所も相手の住所も知らないので、送り元 0.0.0.0、宛先 255.255.255.255(全員あて)で叫びます。
おもしろかったのは、住所が決まるまでに約3秒かかったことです。ルーターは 10.0.1.177 を配る前に、その住所を使っている機械がいないか ARP で3回確かめていました。その間に PC は返事がないと思って Discover をもう一度送ったので、Offer も2つ届いています。
もらった住所には期限(リース)があります。今回は1時間で、半分の 30 分(実際の dhclient はばらつきを入れて 1,714 秒)がたつと「延長してください」と頼み直します。PC を閉じたまま期限が切れた住所は、ほかの機械に配られることがあります。
住所が足りない
32 ビットで作れる住所は 232=約 43 億個。地球の人口より少なく、しかも特別な住所や、昔の大きな割り当てもあります。
IP アドレスの年表
世界の住所の元締めである IANA の在庫は、2011年2月3日に尽きました。日本を含むアジア太平洋の APNIC も、同じ年の4月15日に通常の配分を終えています。それでもインターネットが動き続けているのは、家庭や会社でプライベートアドレスと NAT を使い、たくさんの機械で1つのグローバルな住所を分け合っているからです。そして、根本の解決策が IPv6 です。
IPv6
IPv6 の住所は 128 ビット。作れる数は 2128、IPv4 の 4 倍ではなく、296 倍です。長いので、16 ビットずつ 8 つに区切って 16 進数で書き、0 の続くところを縮めます。
IPv6 の住所の形
この記事のクラウドの Linux には IPv6 の機能が入っていなかったので、ここは Python の ipaddress で計算して確かめます。
>>> import ipaddress
# 0 が続くところは :: に縮め、先頭の 0 は省く
>>> ipaddress.ip_address('2001:0db8:0000:0000:0000:0000:0000:0001').compressed
'2001:db8::1'
# 住所の数
>>> 2 ** 128
340282366920938463463374607431768211456
>>> 2 ** 32
4294967296
# 第3回の MAC から作るリンクローカルアドレス(EUI-64。ff:fe を挟み、ローカルのビットを反転)
>>> def eui64(mac):
... b = bytes.fromhex(mac.replace(':', ''))
... iid = bytes([b[0] ^ 0x02]) + b[1:3] + b'\xff\xfe' + b[3:]
... return 'fe80::' + ':'.join(iid[i:i+2].hex() for i in range(0, 8, 2))
...
>>> ipaddress.ip_address(eui64('02:00:00:00:01:10'))
IPv6Address('fe80::ff:fe00:110')
IPv6 では、機械が自分で住所を作れます。前半 64 ビットはルーターが知らせてくれるネットワークの番号、後半 64 ビットは自分で作る番号です。昔は第3回の MAC アドレスから作っていましたが(上の EUI-64。第3回のローカルのビットがここで反転します)、それでは機械を追いかけられてしまうので、いまの OS はふつう、ランダムな番号を使います。fe80:: で始まる住所は、同じネットワークの中だけで使うリンクローカルアドレスで、IPv6 の機械は必ず持っています。
普及はゆっくりですが、着実です。Google への接続のうち IPv6 を使うものは、2026年4月に初めて約半分に達しました。いまは多くの家庭で IPv4 と IPv6 の両方が動いていて(デュアルスタック)、使える方が選ばれます。サーバーを作る側は、IPv6 でも待ち受けているかを忘れずに確かめましょう(第7回)。
自分の PC で確かめる
| 調べたいこと | Mac | Windows | Linux |
|---|---|---|---|
| 自分の住所とマスク | ifconfig | ipconfig | ip addr |
| デフォルトゲートウェイ | netstat -rn | route print | ip route |
| DHCP でもらった中身 | ipconfig getpacket en0 | ipconfig /all | nmcli -f DHCP4 device show |
| IPv6 で届くか | ping6 | ping -6 | ping -6 |
家の PC で ipconfig や ifconfig を見ると、たいてい 192.168 か 10 で始まる住所(プライベート)と、fe80:: で始まる住所が並んでいるはずです。169.254 で始まっていたら、DHCP から住所をもらえていません。ルーターの電源やケーブル(第2回)から確かめましょう。
結 — 一枚まとめと、次回
- IP アドレスは最後の相手までの住所。IPv4 は 32 ビットで、10.0.1.10 は 0a 00 01 0a の4バイト。
- 「/24」は前から 24 ビットがネットワークの番号=マスク 255.255.255.0。/24 の住所は 256 個、使えるのは 254 個。
- 送る前にマスクで切って比べ、同じなら直接、違えばルーターへ。
- /16 と取り違えると、ルーターの向こうの相手の MAC を尋ね続け、ping は 100% 失敗した。
- プライベート(10・172.16・192.168)、自分自身(127)、DHCP 失敗のしるし(169.254)。
- DHCP は Discover・Offer・Request・ACK。実測では、ルーターの確かめで約3秒かかった。期限は1時間。
- IPv4 の在庫は 2011年に尽きた。IPv6 は 128 ビットで、Google への接続の約半分が IPv6 に。
新井「よそ」と分かったらルーターに渡す……。で、ルーターはどうやって次の行き先を決めてるんですか?
古井ルーターは道案内の表を持っている。次回はその表と、TTL を使って道のりを調べる traceroute、そして家のルーターの正体だ。
参考
- RFC 791 — Internet Protocol (1981)
- RFC 4632 — Classless Inter-domain Routing (CIDR)
- RFC 1918 — Address Allocation for Private Internets
- RFC 6598 — Shared Address Space (100.64.0.0/10)
- RFC 3927 — Link-Local IPv4 Addresses (169.254.0.0/16)
- RFC 2131 — Dynamic Host Configuration Protocol
- JPNIC — IPv4 address pool ran out in the Asia Pacific region
- RFC 8200 — Internet Protocol, Version 6 (IPv6) Specification(RFC 2460 の後継)
- RFC 4291 — IP Version 6 Addressing Architecture
- RFC 8981 — Temporary Address Extensions for SLAAC in IPv6
- APNIC Blog — Google hits 50% IPv6 (2026-04-28)
- Python — ipaddress
記録は、筆者がクラウド上の Linux(Ubuntu 24.04)にネットワーク名前空間で作った練習用ネットワークで、2026年10月24日に取ったものです。DHCP はルーター役の dnsmasq(期限1時間)と dhclient(isc-dhcp-client 4.4.3)、ほかは第1回と同じ構成です。表の数字はすべて、この記録とそのときのコマンドの出力から読んだ実際の値です。この環境のカーネルは IPv6 を持たないため、IPv6 の例は Python の ipaddress による計算です。住所の枯渇の日付は JPNIC、IPv6 の割合は APNIC Blog(Google の統計、2026年4月)によります。登場人物は架空の人物です。
いにしえのネットワーク入門 第4回 — IP アドレス / 2026.10