ソースコードで体感するネットワークの仕組み
~手を動かしながら基礎からTCP/IPの実装までがわかる

書籍の概要

この本の概要

普段あたりまえのようにネットワークを使っていますが,「IPアドレスを持っている」とはどういったことか,本当に理解できているでしょうか。本書では,IPやUDP,TCPを自作し,ネットワークの仕組みを体験。pingのやりとりを行うプログラムを,DHCPクライアント機能の実装,TCPの送受信と切断を行うものへと拡張していくことで,RFCを眺めるだけでは見えにくいプロトコルの全体の流れをつかめます。ソケットライブラリに頼っていては得られない,問題の切り分けや問題発生の予防に役立つ力も身につきます。

こんな方におすすめ

  • ネットワークエンジニア

著者の一言

誰もが,PCにネットワークケーブルを挿して,スイッチングHUBに接続,あるいは,スマートフォンをWi-Fi接続するとインターネットが使えるようになるのは「あたりまえ」だと感じていると思います。しかし,インターネットでの通信の基本である「IPアドレスを持っていること」とはどういう状態なのか?と聞かれてさっと答えられる人は意外と少ないのではないでしょうか。

LANやインターネットの基本となっているイーサネットでは,MACアドレスを宛先として通信を行います。それだけでは不便なのでIPが存在し,今どきの多くのネットワーク機器はIPアドレスをあて先として通信を行っている,というイメージを持っている方は多いでしょう。しかし,それを本当にきちんと理解できているでしょうか。

本書では,IPの下で使われているUDPやTCPといったネットワークの仕組みを,実際にプログラムを作って体験してみます。特にTCPに関しては,「よくわからないけれど,ソケットライブラリを使ってconnectしてsendすればデータが送信でき,recvすれば受信できる」と考えている人が多いと思いますので,自力で3ウェイハンドシェークしたり,シーケンス番号を管理して再送制御したりするプログラムを作って,TCPの基本を体験してみます。

前著『ルーター自作でわかるパケットの流れ』では,イーサネットフレームを自分で中継しながらIPを理解してみましたが,「なにもルーターじゃなくても……」とか「もっと簡単な例で体験するほうが良いのでは?」という意見をいただき,「いっそのことIPや UDP,TCPの仕組みを自作すれば根本からわかるだろう」と考えました。どんどん仕様が追加されてきた現在のTCPの仕組みを全て作ってみるのは大変ですが,拡張機能を使わずに基本部分だけでも十分通信はできます。これらのプログラムが実務で役に立つかどうかは別として(もちろん,役に立つケースはあるのですが),作って体験してみた人の理解は,ただRFCを眺めただけの人に比べれば断然深いものになることでしょう。

誰でも簡単に作って動かしてみることができるのがプログラミングの良いところです。「百聞は一見にしかず」プログラムを動かして様子を見てみるのが一番です!

この書籍に関連する記事があります!

「わかったつもり」になっていませんか?
今や私たちは,ネットワークに接続しない日はありません。しかし,あたりまえのように接続しているネットワークの仕組みについて,あいまいな知識しか持っていない人もいることでしょう。

目次

第1章 本書で扱うプロトコル

1-1 ネットワークプロトコルのおさらい

  • イーサネット:MAC(Media Access Control)アドレス
  • ARP(Address Resolution Protocol)
  • IP(Internet Protocol)
  • ICMP(Internet Control Message Protocol)
  • UDP(User Datagram Protocol)
  • DHCP(Dynamic Host Configuration Protocol)
  • TCP(Transmission Control Protocol)

1-2 階層化されたネットワークプロトコルのイメージ

  • TCPでコネクトするときに流れるデータは?

第2章 pingのやり取りが可能なホストプログラムを作ろう ~仮想IPホストプログラム:第一段階

2-1 仮想IPホストの第一目標

  • 実現する機能
  • 設定ファイル
  • スレッドの構成
  • 関数の構成
  • ソースファイルの構成

2-2 プログラムのメイン処理 ~main.c

  • ヘッダファイルのインクルードと変数の宣言
  • 受信処理
  • コマンドの入力処理を行う
  • 終了処理を行う
  • インターフェースの情報を出力する
  • main関数の記述

2-3 パラメータを読み込んで格納する ~param.c,param.h

  • 必要な値を定義する
  • パラメータ情報を保持する構造体を定義する
  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルードと変数の宣言
  • パラメータのデフォルト値をセットしてファイルから読み込む
  • IPアドレスとサブネットのチェック

2-4 ネットワークユーティリティ関数を準備する ~sock.c,sock.h

  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルード
  • チェックサムを計算する
  • MACアドレスを調べる
  • 処理を一時待機させる
  • ソケットをPF_PACKETとして初期化して送受信に備える

2-5 イーサネットフレームの送受信を行う ~ether.c,ether.h

  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルードと変数の宣言
  • 文字列とバイナリの変換
  • 16進ダンプを行う
  • イーサネットフレームを表示する
  • イーサネットの送受信と内容のチェック

2-6 宛先MACアドレスを調べてARPテーブルにキャッシュする ~arp.c,arp.h

  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルードと変数の宣言
  • ARPヘッダのIPアドレスを文字列に変換する
  • ARPヘッダを表示する
  • ARPテーブルへデータを追加する
  • ARPテーブルを削除する
  • ARPテーブルを検索する
  • ARPテーブルを表示する
  • 宛先MACアドレスを調べる
  • イーサネットにARPパケットを送信する
  • Gratuitous ARPを送信する
  • ARP要求を送信する
  • IPアドレスの重複をチェックする
  • ARPパケットを受信する

2-7 IPパケットの送受信処理を行う ~ip.c,ip.h

  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルードと変数の宣言
  • IPヘッダを表示する
  • IP受信バッファを初期化してデータを追加する
  • IP受信バッファを削除する
  • IP受信バッファを検索する
  • IPパケットを受信する
  • IPパケットをイーサネットに送信する
  • IPパケットを送信する

2-8 ICMPパケットの送受信を行う ~icmp.c,icmp.h

  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルードと変数の宣言
  • ICMPヘッダを表示する
  • ICMPエコー応答を送信する
  • ICMPエコー要求を送信する
  • 受信したICMPパケットを処理する
  • ICMPエコー応答をチェックする

2-9 コマンドを解析して処理する ~cmd.c,cmd.h

  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルードと変数の宣言
  • コマンドごとに処理を行う
  • 各コマンド処理への分岐

2-10 仮想IPホストプログラムを実行する

  • Makefile:makeファイル
  • ビルド
  • 設定ファイルの準備
  • 実行する

2-11 まとめ

  • コラム 本書誕生のきっかけ

第3章 UDP通信に対応させ,DHCPクライアント機能を実装しよう ~仮想IPホストプログラム:第二段階

3-1 仮想IPホストの第二目標

  • 実現する機能
  • 設定ファイル
  • スレッド構成
  • 関数構成
  • ソースファイル構成

3-2 メイン処理に,UDPに関する処理を追加する ~main.c

  • UDP,DHCP関連のヘッダファイルを追加インクルードする
  • 終了時にリース解放を行う
  • リース時間情報を設定する

3-3 設定情報にDHCP関連の情報を追加する ~param.c,param.h

  • リース時間の変数を宣言する
  • リース時間を読み込む

3-4 IPパケットの処理にUDPパケットの送受信を追加する ~ip.c,ip.h

  • UDP関連のヘッダファイルをインクルードする
  • UDPパケットの受信処理を追加する

3-5 ICMPパケットの処理にUDPで必要な処理を追加する ~icmp.c,icmp.h

  • ICMP Destination Unreachableの関数を宣言する
  • 到達不能メッセージを送信する

3-6 UDPのコマンド処理を追加する ~cmd.c,cmd.h

  • UDP関連のプロトタイプ宣言
  • UDP関連のヘッダファイルをインクルードする
  • 文字列データを作成する
  • IP割り当ての情報を表示する
  • UDPテーブルの状態を表示する
  • UDPに関するコマンドを処理する
  • UDPコマンド処理への分岐を追加する

3-7 UDPの処理を行う ~udp.h,udp.c

  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルードと変数の宣言
  • UDPヘッダ情報を表示する
  • チェックサムの計算を行う
  • UDPテーブルの追加,検索,表示をする
  • 空きポートの検索
  • 受信ポートを準備する
  • 受信ポートをクローズする
  • UDPの送信を行う
  • UDPの受信処理を行う

3-8 ネットワークアドレスを動的に割り当ててもらう ~dhcp.h,dhcp.c

  • 定数や構造体を定義する
  • 関数のプロトタイプ宣言
  • ヘッダのインクルードと変数の宣言
  • DHCPパケットの情報をオプションごとに表示する
  • DHCPのオプションの処理
  • DHCPリクエストデータを作成する
  • DHCP各種送信処理
  • 受信したDHCPパケットを解析する

3-9 仮想IPホストプログラムを実行する

  • Makefile:makeファイル
  • ビルド
  • 設定ファイルの準備
  • 実行

3-10 まとめ

第4章 TCP機能の基本機能を追加しよう ~仮想IPホストプログラム:第三段階

4-1 仮想IPホストの第三目標

  • 実現する機能
  • 設定ファイル
  • スレッド構成
  • 関数構成
  • ソースファイル構成

4-2 メイン処理に,TCPに関する処理を追加する ~main.c

  • TCP関連のヘッダファイルを追加インクルードする
  • 終了時にTCP接続を切断する
  • 最大セグメントサイズを表示する

4-3 設定情報にTCP関連の情報を追加する ~param.c,param.h

  • デフォルト値の定義と最大セグメントサイズの変数の追加
  • TCP用のヘッダをインクルードする
  • 最大セグメントサイズのデフォルト値を設定する
  • 最大セグメントサイズを読み込む

4-4 IPパケットの処理にTCPパケットの送受信を追加する ~ip.c,ip.h

  • TCP関連のヘッダファイルをインクルードする
  • TCPパケットの受信処理を追加する

4-5 TCPのコマンド処理を追加する ~cmd.c,cmd.h

  • TCP関連のプロトタイプ宣言
  • TCP関連のヘッダファイルをインクルードする
  • データの生存時間や転送時間などの設定値を表示する
  • TCPテーブルの状態を表示する
  • TCPに関するコマンドを処理する
  • TCPコマンド処理への分岐を追加する

4-6 TCPの処理を行う ~tcp.h,tcp.c

  • 関数のプロトタイプ宣言
  • ヘッダファイルのインクルードと変数の宣言
  • TCPヘッダの情報を表示する
  • TCP状態の文字表記を得る
  • チェックサムの計算を行う
  • TCPテーブルの追加,検索,表示をする
  • 空きポートの検索
  • 接続受付準備を行う
  • ポートをクローズする
  • SYN,FIN,RST,ACKの送信を行う
  • 直接宛先指定でRSTを送信する
  • 接続を行う
  • 接続を解除する
  • データを送信する
  • TCPの受信処理を行う

4-7 仮想IPホストプログラムを実行する

  • Makefile:makeファイル
  • ビルド
  • 設定ファイルの準備
  • 実行

4-8 まとめ

著者プロフィール

小俣光之(こまたみつゆき)

日本シー・エー・ディー株式会社 代表取締役社長。
1989 年新卒で入社後,プログラマとして仕事を続け,2005 年11月から社長となるがプログラマも兼務している。社長としての仕事の割合が年々増える中,ProDHCPやネットワーク関連の新製品開発などネットワークプログラミングだけは続けている。
プログラミング関連の著書を『ルーター自作でわかるパケットの流れ』(技術評論社)など8冊執筆し,プログラマの仕事の素晴らしさを伝えるべく読み物も4冊執筆。『プログラムは技術だけでは動かない』(技術評論社)に続き,本書は13冊目の著書となる。

ブログ:オルタナティブ・ブログ