気温が高い事よりも、湿度が高いのがまいる。 あんまり暑いと用もないのにサーバールーム行きたくなるよね。 っていうか、あそこに机置きたいわ、夏は。 最近、仕事でプログラム関係が多かったりする。 おかしいなぁ、どっちかって言うと、ネットワーク・セキュリティですよね?なんでこんなプログラミングだの、システム分析だの設計だのの話してるんだろう。 慣れない分疲労が激しいです。 んで、本家「Roads to Node」のBBSの方に。 C#で作ったリゾルバの書き込みがあって。 う〜ん。C#わからんしなぁ…。 …Javaで作ってみるかぁ。最近、ちょっとだけソケットがらみの勉強してるし…。 で、できたのがコレ。 import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.ArrayList; import java.util.StringTokenizer; public class DNSResolver { private static final int TIMEOUT = 3000; private static final int PORT = 53; private static final int ROOT = 0; private static final int PACKETLENGTH = 1024; public static void main(String[] args) throws Exception{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //DNSサーバと、質問するドメイン名の入力 System.out.print("DNSサーバ:"); String dnsServer = br.readLine(); System.out.print("ドメイン名:"); String domainName = br.readLine(); //DNSサーバ名の解決 InetAddress svrAddr = InetAddress.getByName(dnsServer); //バイト型のラベル配列 ArrayList<Byte> labelData = new ArrayList<Byte>(); //ドメイン名をTokenizerで分割してラベルにする StringTokenizer st = new StringTokenizer(domainName,"."); while(st.hasMoreTokens()){ String label = st.nextToken(); //ラベル長をラベル配列にいれる int labelLength = label.length(); labelData.add(new Integer(labelLength).byteValue()); //ラベルをASCIIでバイト型にして、ラベル配列に入れる byte labelString[] = label.getBytes("ASCII"); for(int i=0;i<labelString.length;i++){ labelData.add(new Byte(labelString[i])); } } //ラベル配列の最後にルートドメインを示す0x0を入れる labelData.add(new Byte(new Integer(ROOT).byteValue())); //DNSヘッダセクション ID=1、フラグ、QDCount=1 その他カウント=0 byte header[] = {0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00}; //ラベル配列をバイト型の配列に入れる byte QName[] = new byte[labelData.size()]; for(int i=0;i<labelData.size();i++){ QName[i] = labelData.get(i).byteValue(); } //QType=A byte QType[] = {0x00,0x01}; //QClass=IN byte QClass[] = {0x00,0x01}; //DNSメッセージ長 int totalByte = header.length + QName.length + QType.length + QClass.length; //送信用のバイト型配列を作成し、ヘッダ、QName、QType、QClassを入れる byte queryData[] = new byte[totalByte]; System.arraycopy(header,0,queryData,0,header.length); System.arraycopy(QName,0,queryData,header.length,labelData.size()); System.arraycopy(QType,0,queryData,header.length+labelData.size(),QType.length); System.arraycopy(QClass,0,queryData,header.length+labelData.size()+QType.length,QClass.length); //ソケット生成 DatagramSocket socket = new DatagramSocket(); //タイムアウトの設定 socket.setSoTimeout(TIMEOUT); //送信用データグラム DatagramPacket query = new DatagramPacket(queryData,queryData.length,svrAddr,PORT); //受信用バッファ byte replyData[] = new byte[PACKETLENGTH]; //受信用データグラム DatagramPacket reply = new DatagramPacket(replyData,PACKETLENGTH); //データグラム送信 socket.send(query); //データグラム受信 socket.receive(reply); //受信したバイトをString型に変換し、出力 String data = new String(reply.getData(),0,reply.getLength(),"ASCII"); System.out.println(data); } } 一応ネームサーバとやりとりができるところまでは確認した。 まぁ、ReplyはビットをそのままStringで出力してるからまともに読めないけど。 やりとりをキャプチャして、正しく動いているっぽいのでOK。 あと、とりあえず動くものを作ったので、例外処理がないのはご愛嬌。 う〜ん、面白いことは面白いな、プログラミング。 リゾルバなんか作ったら、今度はサーバを作りたくなったりして。まぁ、難易度が全然違うけれど。 改めて見直すと、もっとスマートになりそうな気がする。 気はするのだが、どうしていいかわからないのが困りもの。 そこらへんは、教えてもらったり、本で読んだりしないと身につかないものだからなぁ。 もうちょっと勉強するかなぁ……。 自分のサイト見て、DNSメッセージフォーマット見て、それをそのまま送る、というだけのものだしな。 あぁ、そうそう。DNSを学ぶなら、おススメの本がありますよ? と、うまく宣伝にもっていけたところで今日はここまで。 そんな一日 |
<< 前記事(2009/06/30) | ブログのトップへ | 後記事(2009/07/26) >> |
タイトル (本文) | ブログ名/日時 |
---|
内 容 | ニックネーム/日時 |
---|---|
WireShark+Winpcapを使ってnslookupと同じバイト配列を流してみたら成功。どうやらちゃんと処理が進んだ。 |
himajin100000 2009/07/09 19:19 |
<< 前記事(2009/06/30) | ブログのトップへ | 後記事(2009/07/26) >> |