記事の深堀り。
が、仮想ネットワークドライバの簡単なサンプルプログラムとVPNの仕組みの解説が書かれており、参考になりそうだった。が、記事のサンプルプログラムはカーネル 2.6 向けのもののようで、今普通に使えるOSだと動かないようだった。
例えば、出来るだけ古めでパッと使えたUbuntu 16.04 だと make 時に以下のエラーが出た。
/home/ubuntu/net3/vn.c: In function ‘vn_init’: /home/ubuntu/net3/vn.c:252:5: error: ‘struct net_device’ has no member named ‘open’ dev->open=vn_open; ^ /home/ubuntu/net3/vn.c:253:5: error: ‘struct net_device’ has no member named ‘stop’ dev->stop=vn_stop; ^ /home/ubuntu/net3/vn.c:254:5: error: ‘struct net_device’ has no member named ‘set_config’ dev->set_config=vn_config; ^ /home/ubuntu/net3/vn.c:255:5: error: ‘struct net_device’ has no member named ‘hard_start_xmit’ dev->hard_start_xmit=vn_tx; ^ /home/ubuntu/net3/vn.c:256:5: error: ‘struct net_device’ has no member named ‘do_ioctl’ dev->do_ioctl=vn_ioctl; ^ /home/ubuntu/net3/vn.c:257:5: error: ‘struct net_device’ has no member named ‘get_stats’ dev->get_stats=vn_stats;
どうやら struct net_device 周りが古いようで、<linux/netdevice.h> を見てみると、それっぽい定義が無かった。もしかしたら無くなっている?のかも。
いずれにせよ、かなり書き換えないと動かなそうではある。。 とりあえず、仮想ネットワークデバイスドライバとキャラクタデバイスとトンネルや暗号化のアプリケーションとの関係性がわかればいいので、そのあたりのコマンドや関数( mknod 等)の仕様を確認してみる。
www.mech.tohoku-gakuin.ac.jp → mknod の簡単なサンプルがあった。 デバイスドライバを insmod で登録したらその番号を覚えておき、 mknod でデバイスファイルを作成しつつその番号に紐付けるようにすればいい。 そうすれば、そのファイルにアクセスされたらデバイスドライバにアクセスがされるらしい。
ただし、雑誌のサンプルでは、mknod した後にそのデバイス名で ifconfig .. 192.168.0.1 みたいにアドレスを指定できるネットワークインターフェースとして認識されているので、単純なファイルの作成とは違うみたい。 register_netdev 関数あたりかな。
と思っていると、この前号↓に詳細な解説が書いてあった。 register_netdev 関数でカーネルにデバイスを登録すると、そのときに登録した設定内容にしたがって、カーネルから指定の関数が呼び出されるようになるらしい。このサンプルプログラムも見てみたいところだ。
ちなみに、Amazon Linuxのネットワークドライバ ena のソースは↓みたい。 github.com
register_netdev してる箇所は↓。 amzn-drivers/ena_netdev.c at b91fcd346b903fd2006cea79da7c13993bce5c4b · amzn/amzn-drivers · GitHub
ちょっと書き換えて実験してみたいけど、Amazon Linuxじゃ無理だな。。 オープンソースはRaspberry Pi(Rasbpian)でやってみるか。
カーネルからパケット送信時とかに呼び出されるときのイメージとかをつかめるとTUN/TAPの動作イメージも掴めそう。 TUN/TAPも結局は、仮想ネットワークドライバとネットワークデバイスの1種だろうから。