Try using Java to implement DNS (a)--datagramsocket, Datagrampacket, Message

Source: Internet
Author: User
Tags set socket nslookup

In general, it is not necessary to write your own DNS, the current open-source DNS service software is many, the function is also very powerful. However, sometimes it is necessary and has many advantages. For example, for the enterprise intranet, simplified DNS configuration, can be based on enterprise needs to add new features, very flexible. This article tries to implement one of the simplest DNS services in Java.

DNS is based on the UDP protocol, and the default port is 53.

Implementing the DNS service on your own computer (as a DNS server) requires the program to listen on UDP port 53 first. In Java, UDP-related classes are Datagramsocket and Datagrampacket. See the API for details, or refer to http://www.cnblogs.com/hq-antoine/archive/2012/02/11/2346908.html.

After that, another computer is required as the client, setting the DNS address to the IP address of the server.

 Public classUdpserver {Private Staticdatagramsocket socket;     PublicUdpserver () {//set socket, monitor port        Try {             This. Socket =NewDatagramsocket (53); } Catch(SocketException e) {e.printstacktrace (); }    }     Public voidstart () {System.out.println ("Starting ... \ n ");  while(true) {            Try {                byte[] buffer =New byte[1024]; Datagrampacket Request=Newdatagrampacket (buffer, buffer.length);                Socket.receive (Request); //output DNS request data for clientsInetAddress sourceipaddr =request.getaddress (); intSourceport =Request.getport (); System.out.println ("\NSOURCEIPADDR =" + sourceipaddr.tostring () + "\nsourceport =" +sourceport); System.out.println ("Data =" +NewString (Request.getdata (), 0, Request.getlength ())); } Catch(SocketException e) {System.out.println ("SocketException:");            E.printstacktrace (); } Catch(IOException e) {System.out.println ("IOException:");            E.printstacktrace (); }        }    }}

Run the program error, errors are as follows:

According to the exception prompt, open 53 port exception, need to confirm operation permission. 1024 the following ports are reserved for the default system and can only be used by the root user. Use the root account to run the program, then use the nslookup www.baidu.com command test on the client, and output the following information on the server:

The IP address of the client is 10.211.55.253, the port is 43065, but what is the following data?

Analysis: garbled because the data obtained by Request.getdata () is not a string type, so it cannot be simply rough through the new string (Request.getdata (), 0, Request.getlength ()) Force output to a string type. Guess should be in accordance with the DNS data format of the byte stream, the following through the packet capture software Wireshark analysis.

Found in DNS packets, including fields such as ID, Flags, Questions, Answer RRs, authority RRs, Additional RRs, and queries. If you write a program, by analyzing the byte stream to extract the required information, it is a more troublesome thing. Fortunately there is dnsjava this open source project, inside the message class has helped us to take care of these things.

Change the code as follows,

1  PackageCom.everseeker;2 3 ImportOrg.xbill.DNS.Message;4 5 Importjava.io.IOException;6 ImportJava.net.DatagramPacket;7 ImportJava.net.DatagramSocket;8 Importjava.net.InetAddress;9 Importjava.net.SocketException;Ten  One  Public classUdpserver { A     Private Staticdatagramsocket socket; -  -      PublicUdpserver () { the         //set socket, monitor port -         Try { -              This. Socket =NewDatagramsocket (53); -}Catch(SocketException e) { + e.printstacktrace (); -         } +     } A  at      Public voidstart () { -System.out.println ("Starting ... \ n "); -          while(true) { -             Try { -                 byte[] buffer =New byte[1024]; -Datagrampacket request =Newdatagrampacket (buffer, buffer.length); in socket.receive (request); -                 //output DNS request data for clients toInetAddress sourceipaddr =request.getaddress (); +                 intSourceport =Request.getport (); -System.out.println ("\nsourceipaddr =" + sourceipaddr.tostring () + "\nsourceport =" +sourceport); the //System.out.println ("data =" + New String (Request.getdata (), 0, Request.getlength () )); *  $Message Indata =NewMessage (Request.getdata ());Panax NotoginsengSystem.out.println ("Indata =" +indata.tostring ()); -}Catch(SocketException e) { theSystem.out.println ("SocketException:"); + e.printstacktrace (); A}Catch(IOException e) { theSystem.out.println ("IOException:"); + e.printstacktrace (); -             } $         } $     } -}

Re-test, the output information is:

found that the output information is consistent with the information we get through the packet capture. Among them, questions recorded the need to resolve the domain name Www.baidu.com,type to a. And answers is empty, because this is a domain name resolution request information, the following we only need to put the results of the resolution into the answers this field, and return to the client, that is, the simplest DNS functionality has been completed.

Analysis of the source code of Dnsjava, found in the message class has a variable private List [] sections, length of 4, recorded questions, Answers, authority RRs, Additional RRs 4 fields. Change the code as follows,

1  PackageCom.everseeker;2 3 Importorg.xbill.dns.*;4 5 Importjava.io.IOException;6 ImportJava.net.DatagramPacket;7 ImportJava.net.DatagramSocket;8 Importjava.net.InetAddress;9 Importjava.net.SocketException;Ten  One  Public classUdpserver { A     Private Staticdatagramsocket socket; -  -      PublicUdpserver () { the         //set socket, monitor port -         Try { -              This. Socket =NewDatagramsocket (53); -}Catch(SocketException e) { + e.printstacktrace (); -         } +     } A  at      Public voidstart () { -System.out.println ("Starting ... \ n "); -          while(true) { -             Try { -                 byte[] buffer =New byte[1024]; -Datagrampacket request =Newdatagrampacket (buffer, buffer.length); in socket.receive (request); -                 //output DNS request data for clients toInetAddress sourceipaddr =request.getaddress (); +                 intSourceport =Request.getport (); -System.out.println ("\nsourceipaddr =" + sourceipaddr.tostring () + "\nsourceport =" +sourceport); the                 //parsing DNS packet formats *Message Indata =NewMessage (Request.getdata ()); $System.out.println ("\nindata =" +indata.tostring ());Panax NotoginsengRecord question =indata.getquestion (); -System.out.println ("question =" +question); theString domain =indata.getquestion (). GetName (). toString (); +System.out.println ("domain =" +domain); A                 //Resolving domain Names theInetAddress answeripaddr =address.getbyname (domain); +Message Outdata =(Message) Indata.clone (); -                 //because the received request is of type A, the answer is also arecord. View the inheritance of the record class, and find Aaaarecord (IPv6), Cnamerecord, etc. $Record answer =NewArecord (Question.getname (), Question.getdclass (), 64, answeripaddr); $ Outdata.addrecord (answer, section.answer); -                 //send a message to the client -                 byte[] buf =Outdata.towire (); theDatagrampacket response =NewDatagrampacket (buf, Buf.length, sourceipaddr, sourceport); - socket.send (response);Wuyi}Catch(SocketException e) { theSystem.out.println ("SocketException:"); - e.printstacktrace (); Wu}Catch(IOException e) { -System.out.println ("IOException:"); About e.printstacktrace (); $             } -         } -     } -}

To continue the test, the client nslookup www.baidu.com and outputs the result:

The test was successful, so that one of the simplest DNS was done.

Try using Java to implement DNS (a)--datagramsocket, Datagrampacket, Message

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.