学習⽤TCP/IPプロトコルスタックのIPv6対応〜アプリケーションプロトコルスタックの利活⽤〜
学習駆動コース 横尾和真
背景: 学習⽤TCP/IPスタック "microps[1]"l TCP/IPスタックの⾃作や
l カーネルによるTCP/IPの処理はソケットプログラミングは、⾼性能だがブラックボックス状態
IPv4を前提にした実装が多い→ ⾃作することで理解を深める

実⽤性の検討

ユーザアプリケーション

l 実装を進めているうちに、アプリ
ケーションとして動作するTCP/IP
プロトコルスタックを「学習⽤」としてのみ消化するのは勿体無いと感じるように..
l 実⽤的なユースケースを考えてみることに！

ユーザアプリケーション

microps

ユーザアプリケーション

Socket Like API
Socket API
AF_INET

AF_INET6

IPv6スタックを追加実装し、l IPv6の普及率は年々少しずつ増加しており、知らないうち 公開することで今後IPv6を学習する⼈にとっても有⽤なものにしたい！にIPv6を使っている

AF_INET…

AF_INET6

AF_PACKETTAPデバイス

TCP/IP

TCP/IPIPv6スタック

擬似デバイスドライバ

デバイスドライバ
NIC

microps の概要と追加実装の位置付け

SecHack365で年間通して⾏った活動
5⽉

6⽉
①7⽉

8⽉

②③10⽉

9⽉
④11⽉
⑤12⽉

2
⽉

1
⽉

⑥3⽉

⑦IPv6 実装

実⽤性の検討① IPv6 基本部の実装⑦ 実⽤性の検討＆プロトタイプの実装

l FreeBSD の IPv6 実装（KAME[2]）などを参考に実装

l アプリケーションスタック（microps ）の特徴

l 128 ビットアドレスを扱う- 標準で 128 ビットを扱える型がないので定義- IPv6 アドレスの省略表記に対応した ntop・pton の実装
l IPv6 ヘッダ構造体の定義
l IPv6 パケットの⼊出⼒・マルチキャストの受信
2001:00db:0000:0000:1234:5678:9abc- ip6_input / ip6_output↓（省略）
2001:db8::1234:5678:9abc

l Echo Request/Reply，Destination Unreachable，Packet Too Big，Time Exceededl NDP（Neighbor Discovery Protocol）

l 既存アプリの再利⽤

Link Local Address を⽣成し、SLAAC を開始している様⼦

Router Advertisement を受け取って、Global Unicast Address を⾃動⽣成している様⼦（DAD は未実装）③ SLAAC の実装
l Stateless Address Auto Configuration: アドレスの⾃動設定
l MAC ドレスを元に拡張 EUI-64 形式でインターフェース識別⼦を⽣成④ IPv6 Forwarding の実装
l アプリケーション実装の IPv6 ルータと Network Namespace による動作確認
2001:db8:1::/64

microps（アプリケーション）

User
Socket API

Socket API

AF_PACKET/SOCK_RAW

AF_PACKET/SOCK_RAW

デバイスドライバ

デバイスドライバ

NIC 1

NIC 2

パケット:1:2:1

router1（microps + IPv6 fwrd）

host1

write()

2001:db8:3::/64

router2:2
host2

Linux で使われる fd とmicrops 内部で使⽤する識別⼦をマッピングØ 同名の関数を定義し、内部で microps の Socket
関数（ sock_open() ）を呼び出す

socket()Ø 標準Cライブラリで定義されている Socket 関数

libc

socket(2)/*サーバ側 で、nc コマンドを⽤いて待ち受ける */パケット「単なるファイル I/O」や「SNSへの投稿」などを通信媒体にtraceroute の様⼦/* クライアント側 で、LD_PRELOAD を利⽤してnc コマンドを実⾏し、接続する */sock_connect，sock_send，sock_recv）
アドレスファミリーをセッl 「AF_INET6」を扱えるように追加実装
トで保持することIPv4/IPv6
アドレスのどちらを扱って
l sockaddr 構造体の定義（ntopやptonを含む） いるのかが常にわかるl アドレスファミリーとアドレスをセットで扱う→ asoc = sock_open(AF_INET6, SOCK_STREAM, IPPROTO_TCP);/*これらの関数を hook する */パケwrite()/* poll() は hook していない */ッpollinトread()g..

LD_PRELOAD を利⽤して、netcat コマンドを microps 上で動作させている様⼦

l 通信媒体の抽象化

ファイル I/O・USB・SNS・光・⾳・メール etc..
通信媒体の抽象化の例

l 媒体ごとにプロトコルを定義する必要がなく、データのやりとりさえできれば、TCP/IPで通信できる【エンドポイントを表すフォーマット】[2001:db8:::1234:5678:9abc]:8080⑥ 動作確認（アプリケーションの実装など）/* ファイルに ping パケットのバイナリデータを書き込む */l Web サーバの実装

パケットのバイナリデータが書き込まれたファイル

l カーネルとは独⽴した IPv6 プロトコルスタック
上で実装したアプリケーションの⼀例/* ファイルを監視し、変更時に差分をパケットデータとして読み込む */BLOG での⼿順公開l TCP/IP プロトコルスタックの整合性を確認するツール
l ランダムなデータを持つ IPv6 パケットを⽣成し、それらに対して適切な処理ができているかをチェック

l micropsは、作者の⽅が⽇本語のドキュメントを無料で公開しており、誰でも取り組みやすい内容になっている

ヘッダに含まれる Length Field の値と実際のパケット⻑の整合性の確認不⾜による Segmentation Fault を確認・修正
Webサーバ over ⾃作IPv6スタックにブラウザでアクセスした様⼦
不完全なパケットを受け取ったときのログ

Contact: kzm-yokoo@hiroshima-u.ac.jp / yykzmnet@gmail.com
作品のURL: https://github.com/y-kzm/microps← ファイル I/O で TCP/IP 通信をしている様⼦

Webサーバ over ⾃作IPv6スタックのログ

l ISIC（IP Stack Integrity Checker）[3] を⽤いたテスト

2024/3/6

sample.c…
soc = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);…

microps の Socket 関数を代わりに呼び出す

l microps では，アプリケーション開発がしやすいように Socket Like な API が⽤意されている（sock_open，sock_close，sock_bind，sock_listen，sock_accept，

ISIC がさまざまな IPv6 パケットを⽣成している様⼦$ LD_PRELOAD=./hook.so ./sample
l aahook.soKernel⑤ Socket Like API の AF_INET6 対応の実装

ll 置き換えたい関数を定義した共有オブジェクトを指定して実⾏することで 優先してリンクさせられるため、標準ライブラリの特定の関数を⾃前のものに置き換えられる

パread():1:2

IPv6フォワーディング処理

2001:db8:2::/64

l 既存のアプリケーションを⾃作スタック上で動かすことができれば、キラーアプリケーションを実装することなくアプリケーションスタックの恩恵を受けられる→ 環境変数 LD_PRELOAD を利⽤

ト- MACアドレス解決- IPv6 特有の on-link / off-link に苦戦

ケッ② ICMPv6（NDPなど） の実装

l ライブラリ化されており、Socket Like な API も提供されているため、プロトコルスタックを含めて1つのアプリケーションとして動作可能
l あくまでもアプリケーションとして動作するので、カーネル保護機構を使える
l カーネルをビルドせずに、アプリケーションごとにネットワーク機能の追加やアップデートが可能
l 通信媒体の抽象化が⽐較的容易に実現できる
l microps 上で動くキラーアプリケーションも含めて実装する必要がある→ IPv6 対応を Next Step として取り組めるように⼿順を公開

l ahttps://blog.hatena.ne.jp/y_kzm【参考⽂献】[1] microps, https://github.com/pandax381/microps [2] KAME, https://www.kame.net [3] ISIC, https://github.com/IPv4v6/isic1