DNSプロトコルのQuestionセクションのフォーマットについて調べた。
全体像
DNSプロトコルの全体像
+---------------------+ | Header | +---------------------+ | Question | ←今回はここ +---------------------+ | Answer | +---------------------+ | Authority | +---------------------+ | Additional | +---------------------+
DNSプロトコルのQuestion全体像
1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / QNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QCLASS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
QNAME
質問するドメイン名。
逆引き(PTRレコード)の問い合わせの場合は、in-addr.arpaドメインを使う。
google.co.jp.をドメイン/FQDNと呼ぶ。
googleやcoなどをラベルと呼ぶ。
生成方法
ドメインをラベルに分割。
ラベルのバイト数を1バイトで表現したものとラベルを繋げる。
最後は「.」だけなので長さの0x00だけが付け加えられてNULL終端になる。
ラベルサイズの上位2bitが1の場合、ラベル圧縮の位置として扱われる。
(ラベル圧縮に関してはいずれ書く予定)
ラベルは63バイト以下じゃなきゃいけない。
ドメインは255バイト以下じゃないといけない。
生成プログラム
<?php echo makeQNAME('google.co.jp.'); function makeQNAME($domain) { $label_arr = explode('.', $domain); $result = ''; for ($i=0; $i<count($label_arr); $i++) { $label = $label_arr[$i]; $len = pack('C', strlen($label)); $result .= $len.$label; } return $result; }
$ php qname.php | xxd 0000000: 0667 6f6f 676c 6502 636f 026a 7000 .google.co.jp.
QTYPE
問い合わせるレコードの種類。
2バイトで表現する。
1 => A
2 => NS
5 => CNAME
6 => SOA
12 => PTR
15 => MX
16 => TXT
255 => ANY
QCLASS
問い合わせるクラスの種類。
2バイトで表現する。
通常はIN(Internet)を使う。
それ以外は使った事がないので詳しい事は不明。
1 => IN
3 => CH
4 => HS
参考URL
RFC1035 ドメイン名−実装と仕様書
http://www5d.biglobe.ne.jp/~stssk/rfc/rfc1035j.html
第66回 DNS(5) DNSメッセージ
http://www5e.biglobe.ne.jp/aji/3min/66.html