オルタナティブ・ブログ > プログラマー社長のブログ >

プログラミングでメシが食えるか!?

ルータを作ってみた

»

ルータを作ったと言っても、ハードを作ったのではなく、プログラムでルータを実現してみた、という話です。久々にプログラマー社長らしく、プログラミングネタです。

ルータの役割としては、異なるセグメントのネットワークをつなぐということになります。一般的にはインターネットルータとしてISPとの間でPPPoEなどで接続を確立したり、あるいはグローバルアドレスを使い回すためにNATやIPマスカレードをする機能が目立ちますが、本来は異なるセグメントをつなぐのがルータの役目です。

同一セグメント内の通信は、IPアドレスに対応するMACアドレスを調べて、MACアドレス宛にパケットのやりとりをして実現しています。IPアドレスからMACアドレスを調べるためには、ARPという仕組みが使われます(IPv4の場合)。あるIPアドレスに対応するMACアドレスを調べる際には、「このIPアドレスは誰?」とセグメント全体に対してARPリクエストをブロードキャストし、そのIPアドレスを使っている機器から「俺だよ!」とMACアドレス付きの応答が来てわかるようになります。

異なるセグメントではブロードキャストが使えないので、その仕組みでは通信できないわけです。そこで、仲介役のルータが登場します。それぞれの機器は同一セグメントでない場合、このルータにパケットを送るという、デフォルトルートとかデフォルトゲートウェイと呼ばれる設定にルータのIPアドレスを指定します。デフォルト以外に固定でいくつも経路を登録することもできます。いずれにしても、ルータは他のセグメント宛のパケットの仲介を依頼されます。ルータはその宛先に向けて、次にどのルータに送ればよいかを判断し、次のルータにパケットを送ります。基本的には宛先のMACアドレスを次のルータのMACアドレスに書き換えてパケットを送ることになります。NATやIPマスカレードを使う場合はさらにもう少しパケットを書き換えます。いずれにしても、ルータの連携を繰り返して、最終的に目的の機器にパケットを到達させ、応答をまた逆の手順で戻す、という仕事がルータの役割です。

ルータはインターネットルータであれば専用のものがいくらでも売られていますし、Linuxなどを使えば簡単に設定だけで実現できます。なぜそんなものをわざわざプログラミングするのか、ということになるのですが、特殊なルータを実現したいからです。残念ながら何をしたいのかは、お客さんと一緒に進めていることなのでまだ秘密ですが、プログラムを作れば特殊なものでも簡単に既存の装置を使って実現できます。もちろん専用機をハードで作る方が高性能であったり、量産すればコストが下がったりしますが、「特殊」なものが目的なので、プログラムで実現できればそれでいいのです。

ということで、実際にプログラミングしてみると、リンクレイヤーのパケットを扱うことができれば大したことはありません。基本的に宛先のMACアドレスの書き換えが必要なこと以外は、単に転送すればいいだけです。ただし、IPアドレスからMACアドレスを調べること(ARP関連)だけは少々面倒で、ioctl()を使うのですが、あまり情報がありません。

本当は2時間くらいでプロトタイプを作れると思っていたのですが、ARP関連で少し試行錯誤して半日くらいかかってしまいました。

普段何気なく使っているルータも、作ってみればより仕組みがわかりますし、仕組みがわかれば、こんなこともできるかな?と新しいアイディアも出てくるものです!

Comment(0)