ArduinoをDNSサーバにする (プロトタイプ)
ArduinoのEthernetライブラリ(W5100)はTCP通信と共にUDP通信をサポートしている。そこで、試しにDNSサーバを作ってみた。
横着をするために、まずは小さいDNSサーバ実装をググって探した。その結果、Mini Fake DNS server « Python recipes « ActiveState CodeとTwisted Documentation: Creating and working with a names (DNS) server(実際のモジュール:twisted.namesは$PYTHONPATH/site-packages/twisted/namesにある)を見つけた。
これら実装例を見ながら、RFC 1035 - Domain names - implementation and specificationとDNS, Domain Name Systemを見てパケットの中身を確認しつつ実装した。
このArduino DNSサーバはいかなるリクエスト(ドメイン名)に対しても192.168.0.100 (resIp)を対応するIPアドレスとして返す。
Ethernetライブラリを用いたUDP通信で、文字列ではないデータを送るにはUdp.sendPacket((uint8_t *)buffer, (uint16_t)len, remoteIp, remotePort)を使う必要がある。
このArduino DNSサーバが正しく動作しているかは、digコマンドでチェックした。
$ dig @192.168.254.100 foo.saekiyoshiyasu.org ; <<>> DiG 9.6.0-APPLE-P2 <<>> @192.168.254.100 foo.saekiyoshiyasu.org ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24247 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;foo.saekiyoshiyasu.org. IN A ;; ANSWER SECTION: foo.saekiyoshiyasu.org. 60 IN A 192.168.0.100 ;; Query time: 27 msec ;; SERVER: 192.168.254.100#53(192.168.254.100) ;; WHEN: Fri Jan 14 23:24:46 2011 ;; MSG SIZE rcvd: 56
もちろん、これは正しいDNSサーバの挙動とは言えない。リクエスト毎に適切なIPアドレスを返す必要がある。僕はLAN内用DNSサーバにdnsmasqを使っている。dnsmasqはルーティングテーブルを/etc/hostsから生成する。これを参考にして、Ethernet ShieldからmicroSDカード内のhostsファイルを読んで、ドメイン名とIPアドレスの対応を生成し、適切なレスポンスをするDNSサーバを作りたいと考えている。