BSD本の1st/2nd Editionに対応するFreeBSDカーネルソースを取得する

# BSD本の1st/2nd Editionに対応するFreeBSDカーネルソースを取得する

FreeBSDカーネル内部を解説する[BSDカーネルの設計と実装-FreeBSD詳解-](http://www.amazon.co.jp/dp/4756146791 "BSDカーネルの設計と実装-FreeBSD詳解-")という本があり、その本を皆で読み合わせる[BSDカーネルの設計と実装 読書会](http://connpass.com/series/370/ "BSDカーネルの設計と実装 読書会")が定期的に開催されています(次回は[4/5(日)](http://connpass.com/event/13047/ "BSDカーネルの設計と実装 読書会 (33)")に開催されます)。

この本（通称「BSD本」）なのですが、昨年に[改訂版(2nd Edition)](http://www.amazon.co.jp/dp/0321968972/ "The Design and Implementation of the FreeBSD Operating System (2nd Edition)")が出版されており、先の読書会と同じ4月(4/9;木)に開催される[第36回 FreeBSD勉強会](https://atnd.org/events/63980 "第36回 FreeBSD勉強会")では、この改訂版の読書会が行われるようです。

今回は備忘録と勉強会参加準備を兼ねて、BSD本の1st/2nd Editionに対応するFreeBSDカーネルソースの取得方法をまとめてみました。

## 対応するFreeBSDカーネルバージョン

書籍と対応するFreeBSDのカーネルバージョンは以下となっています。

<table border="1">
<tr><th>BSD本</th><th>FreeBSDバージョン</th></tr>
<tr><td>1st Edition</td><td>FreeBSD-5.2-RELEASE</td></tr>
<tr><td>2nd Edition</td><td>FreeBSD-11.0-CURRENT</td></tr>
</table>

BSD本の2nd Editionでは"This book is about the internal structure of the FreeBSD 11 kernel"と記載されて(P.xxiiiの"Material Covered in this Book")いますが、現段階のFreeBSD 11はCURRENTという位置づけになっています。

## 必要なパッケージ

FreeBSDカーネルソースコードはSubversionで管理されているので、事前に必要なパッケージをインストールします。FreeBSD 11の環境では以下のコマンドを実行します。

```shell-session
# sudo pkg install subversion
```

## カーネルソースコードの取得

以下の手順でカーネルソースを取得します。この例では一般ユーザの$HOME/local/src以下にチェックアウトしています。

```shell-session
$ mkdir -p $HOME/local/src
$ cd $HOME/local/src
$ svn checkout https://svn0.us-west.FreeBSD.org/base/release/5.2.0/sys/ ./5.2R/sys
$ svn checkout https://svn0.us-west.FreeBSD.org/base/head/sys/ ./CURRENT/sys
```

これでBSD本の1st Edition(FreeBSD-5.2-RELEASE)と2nd Edition(FreeBSD-11.0-CURRENT)のソースコードが手元に用意できました。

## 変更になった箇所を追いかけてみる

試しに変更になった箇所をちょっと追いかけてみます。sys/netinet/ip_icmp.cとか見てみると、ICMP_SOURCEQUENCHが削除されています。

```shell-session
$ cd $HOME/local/src
$ diff -u 5.2R/sys/netinet/ip_icmp.c CURRENT/sys/netinet/ip_icmp.c
...中略...
@@ -375,22 +451,15 @@
                if (code > 1)
                        goto badcode;
                code = PRC_PARAMPROB;
-               goto deliver;
-
-       case ICMP_SOURCEQUENCH:
-               if (code)
-                       goto badcode;
-               code = PRC_QUENCH;
        deliver:
```

ICMP_SOURCEQUENCH...？、何じゃそりゃと思いながらsvn blameで見てみると、リビジョンr274359で変更されています。

```shell-session
$ svn blame CURRENT/sys/netinet/ip_icmp.c
...中略...
  1541    rgrimes       case ICMP_MASKREPLY:
274359   melifaro       case ICMP_SOURCEQUENCH:
  1541    rgrimes       default:
```

svn logで追いかけると、ICMP_SOURCEQUENCHは[RFC 6633](https://tools.ietf.org/html/rfc6633 "RFC 6633")で廃止されたため、ソースコードから削除したのだということが分かります。

```shell-session
$ svn log CURRENT/sys/netinet/ip_icmp.c | grep -A6 r274359 
r274359 | melifaro | 2014-11-11 08:10:01 +0900 (火, 11 11 2014) | 4 lines

Remove kernel handling of ICMP_SOURCEQUENCH.
It hasn't been used for a very long time.
Additionally, it was deprecated by RFC 6633.

------------------------------------------------------------------------
```

ちなみに、ICMP_SOURCEQUENCHは[RFC 1812](https://tools.ietf.org/html/rfc1812#section-4.3.3.3 "RFC 1812")の時点で推奨されないICMPメッセージとなっています。RFC 6833で正式にICMP_SOURCEQUENCHは廃止と相成ったようです。

## まとめ

BSD本の1st/2nd Editionに対応するFreeBSDカーネルソースの取得方法をまとめてみました。変更箇所を追いかけてみる話はすこし横道にそれる感じでしたが、ソースコードの変更箇所からRFCでのICMP_SOURCEQUENCH廃止の経緯が垣間見えてくるのは面白いですね。