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

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

ルーターの自作:さらに続き

»

なぜか意外とアクセスがある、ルーターの自作ネタに気をよくして、さらに書きます!
ルーターを作ってみた
ルーターの自作:つづき

今回は、実際にルーターはどんなことをすれば良いかを書いてみましょう。

まず、ルーターが扱うパケットは、IPパケットです。イーサーネットでのIPパケットは、


イーサヘッダ
IPヘッダ
データ:UDP/TCPなど

という感じになっています。

ルーターは2つ以上のセグメントを中継するためのものですので、最低でも2つのネットワークインターフェースを使います。あるインターフェースからパケットを受信し、宛先がインターフェースのセグメントと一致しなければ、もう片方のインターフェースから送信します。その際に、そちらのインターフェースのセグメントと同じであれば、宛先IPアドレスからMACアドレスを調べて、そのMACアドレス宛に送ります。そうでなければ次のルーター宛に送ります。

受信データも送信データもMACアドレスの情報まで必要なので、リンクレイヤーでパケット送受信しなければなりません。パケットを受信したら、ルータとして扱う対象のIPパケットかどうかを確認し、IPチェックサムを確認したり、必要であればUDP/TCPのチェックサムも確認します。IPヘッダのTTLが1だった場合にはそれ以上転送してはいけません。TTLが1だった場合は、ICMPのTime Exceededを送信元に通知します。

パケットを別のインターフェースから送出する際には、MACアドレスの書き換えが必要になります。MACアドレスはイーサヘッダにあるデータです。イーサヘッダの宛先MACアドレスを、送り先のMACアドレスに、送信元MACアドレスを、送出インターフェースのMACアドレスに書き換えます。

さらに、IPヘッダのTTLをカウントダウンします。TTLはルーターを通過するたびに1つ減算し、1だったらそれ以上転送しない、という仕組みになっています。IPヘッダを書き換えた場合、IPチェックサムを再計算して更新しておきます。

これで転送用のパケットが完成した状態になり、次の宛先に送信します。

言葉で書くと複雑そうですが、ソースにすれば大したことではありません。意外と面倒なのはこれまでにも書いたように、ARPを使って宛先IPアドレスから宛先MACアドレスを得ることです。

なお、リンクレイヤーでパケットを扱うためには、OS毎に少々やり方が異なり、
・Linux:SOCK_RAWでsocket()
・BSD:BPFを使用
・Solaris:DLPIを使用
・Windows:libpcapとかを使う?
となります。個人的に簡単なのはLinuxで、次にBSD、SolarisのDLPIは情報が少なく面倒で、Windowsは私の専門外、という感じです。

興味がわいてきた方は、是非自作してみましょう!

Comment(0)