DNS服务检测

原帖地址    http://blog.youkuaiyun.com/stevexk/article/details/2270346

TestDns.java

import java.io.IOException;
import java.io.InterruptedIOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.ConnectException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NoRouteToHostException;
import java.net.UnknownHostException;

public class TestDns {
    public static void main(String[] args){
        // get the parameters
        //
        int retry = 2;
        int port = 53;
        int timeout = 3000;

        // Host to lookup?
        //
        String lookup = "www.google.com";
        if (lookup == null || lookup.length() == 0) {
            // Get hostname of local machine for future DNS lookups
            //
            try {
                lookup = InetAddress.getLocalHost().getHostName();
            } catch (UnknownHostException ukE) {
                // Recast the exception as a Service Monitor Exception
                //
                ukE.fillInStackTrace();
                throw new UndeclaredThrowableException(ukE);
            }
        }

        // get the address and DNS address request
        //
        InetAddress ipv4Addr = null;
        try {
            ipv4Addr = InetAddress.getByName("165.87.13.129");
        } catch (UnknownHostException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        DNSAddressRequest request = new DNSAddressRequest(lookup);

        int serviceStatus = -1;
        DatagramSocket socket = null;
        long responseTime = -1;
        try {
            socket = new DatagramSocket();
            socket.setSoTimeout(timeout); // will force the
                                            // InterruptedIOException

            for (int attempts = 0; attempts <= retry && serviceStatus != 1; attempts++) {
                try {
                    // Send DNS request
                    //
                    byte[] data = request.buildRequest();
                    DatagramPacket outgoing = new DatagramPacket(data, data.length, ipv4Addr, port);
                    long sentTime = System.currentTimeMillis();
                    socket.send(outgoing);

                    // Get DNS Response
                    //
                    byte[] buffer = new byte[512];
                    DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
                    socket.receive(incoming);
                    responseTime = System.currentTimeMillis() - sentTime;

                    // Validate DNS Response
                    // IOException thrown if packet does not decode as expected.
                    request.verifyResponse(incoming.getData(), incoming.getLength());
                    System.out.println(incoming.getAddress());
                    
                    System.out.println("poll: valid DNS request received, responseTime= " + responseTime + "ms");
                    serviceStatus = 1;
                } catch (InterruptedIOException ex) {
                    // Ignore, no response received.
                }
            }
        } catch (NoRouteToHostException e) {
            e.fillInStackTrace();
            System.out.println("No route to host exception for address: " + ipv4Addr);
        } catch (ConnectException e) {
            // Connection refused. Continue to retry.
            //
            e.fillInStackTrace();
            System.out.println("Connection exception for address: " + ipv4Addr);
        } catch (IOException ex) {
            ex.fillInStackTrace();
            System.out.println("IOException while polling address: " + ipv4Addr);
        } finally {
            if (socket != null)
                socket.close();
        }

        // Store response time if available
        //
        if (serviceStatus == 1) {
            System.out.println("response time="+responseTime);
        }
    }
}


DNSAddressRequest.java

//
// This file is part of the OpenNMS(R) Application.
//
// OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc.  All rights reserved.
// OpenNMS(R) is a derivative work, containing both original code, included code and modified
// code that was published under the GNU General Public License. Copyrights for modified 
// and included code are below.
//
// OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
//
// Copyright (C) 1999-2001 Oculan Corp.  All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// For more information contact:
//      OpenNMS Licensing       <license@opennms.org>
//      http://www.opennms.org/
//      http://www.opennms.com/
//


import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;

/**
 * <P>
 * DNSInputStrean extends a ByteArrayInputStream and has methods to decode the
 * data of a DNS response to an address resquest.
 * </P>
 * 
 * @author <A HREF="mailto:sowmya@opennms.org">Sowmya </A>
 * @author <A HREF="http://www.opennms.org">OpenNMS </A>
 * 
 */
public class DNSInputStream extends ByteArrayInputStream {
    /**
     * <P>
     * Constructs a new input stream for decoding DNS records.
     * </P>
     * 
     * @param data
     *            The array of data to pass to the base class.
     */
    public DNSInputStream(byte[] data) {
        super(data);
    }

    /**
     * <P>
     * Constructs a DNSInputStream object from the byte array.
     * </P>
     * 
     * @param data
     *            byte array containing the response data
     * @param off
     *            offset of the data in the byte array
     * @param len
     *            length of the byte array
     */
    public DNSInputStream(byte[] data, int off, int len) {
        super(data, off, len);
    }

    /**
     * <P>
     * Read a byte off the input stream.
     * </P>
     * 
     * @return The integer read.
     * 
     * @exception java.io.IOException
     *                Thrown if the end-of-file is encountered trying to read
     *                the next byte.
     */
    public int readByte() throws IOException {
        int rc = read();
        if (rc == -1)
            throw new EOFException("end of buffer on read");
        return rc;
    }

    /**
     * <P>
     * Read a 'short' off the input stream.
     * </P>
     * 
     * @return The short from the input stream.
     * 
     * @exception java.io.IOException
     *                Thrown if the end-of-file is encountered trying to read
     *                the next short.
     */
    public int readShort() throws IOException {
        return (readByte() << 8 | readByte());
    }

    /**
     * <P>
     * Read an 'int' off the input stream.
     * </P>
     * 
     * @return The int from the input stream.
     * 
     * @exception java.io.IOException
     *                Thrown if there is an error while read.
     */
    public long readInt() throws IOException {
        long rc = 0;
        for (int i = 0; i < 4; i++)
            rc = (rc << 8) | readByte();
        return rc;
    }

    /**
     * <P>
     * Read a 'string' off the input stream.
     * </P>
     * 
     * @return the string from the input stream
     * 
     * @exception java.io.IOException
     *                Thrown if there is an error while read
     */
    public String readString() throws IOException {
        int len = readByte();
        if (len == 0) {
            return "";
        }

        byte[] buffer = new byte[len];
        int rc = read(buffer);
        if (rc == -1 || rc != len)
            throw new EOFException("end of file while reading array");

        return new String(buffer);
    }

    /**
     * <P>
     * The readDomainName method is used to read an entire domain name from the
     * stream. The string returned will be the concatentation of several
     * substrings, each substring in the record is separated by a '.'(dot). For
     * more information see the RFC for the distributed name service.
     * </P>
     * 
     * @return The domain name string.
     * 
     * @exception java.io.IOException
     *                Thrown if an error occurs decoding the string from the
     *                stream.
     */
    public String readDomainName() throws IOException {
        //
        // Check to make sure that we are not going
        // to index the array and generate an bounds
        // exception.
        //
        if (pos >= count)
            throw new EOFException("EOF reading domain name");

        //
        // check the length byte. If the upper two bits are
        // not set then it is a normal string and can be
        // decoded using the readString() method.
        //
        if ((buf[pos] & 0xc0) == 0) {
            String label = readString();
            if (label.length() > 0) {
                //
                // get the next component(s) of the
                // domain name. This is a recursive call.
                // If the length is not equal to null then
                // append the tail and return the new domain
                // name.
                //
                String tail = readDomainName();
                if (tail.length() > 0)
                    label = label + '.' + tail;
            }

            return label;
        }

        //
        // If this point in the code is reached then
        // compression is being used!
        //

        //
        // If the upper two bits were set then this is a special
        // encoding that points us to somewhere else in the record!
        // We have to read that part of the record and to get the
        // next element in the stream.
        // 
        // Throw an I/O exception if the compression offset is
        // malformed.
        //
        if ((buf[pos] & 0xc0) != 0xc0)
            throw new IOException("Invalid domain name compression offset");

        //
        // read the short that is the pointer to the other
        // part of the stream. Note buf is a protected buffer.
        //
        int offset = readShort() & 0x3fff;
        DNSInputStream dnsIn = new DNSInputStream(buf, offset, buf.length - offset);
        return dnsIn.readDomainName();
    }

    /**
     * <P>
     * Reads the resource record from the input stream.
     * </P>
     * 
     * @return The DNSAddressRR that is in response to the address request.
     * 
     * @exception java.io.IOException
     *                Thrown if data does not decode to a DNSAddressRRl.
     */
    public DNSAddressRR readRR() throws IOException {
        String rrName = readDomainName();
        int rrType = readShort();
        int rrClass = readShort();
        long rrTTL = readInt();
        int rrDataLen = readShort();

        //
        // Convert the length of data in this byte array input stream
        // into a "substream" of data. The only way this could get
        // complicated is if there are multiple threads using this
        // stream. If that is the case then synchronization code
        // should be used to wrap the next two lines -- Weave
        //
        DNSInputStream rrDNSIn = new DNSInputStream(buf, pos, rrDataLen);
        pos += rrDataLen;
        try {
            //
            // Create the route record and return it to
            // the caller.
            //
            DNSAddressRR rr = new DNSAddressRR(rrName, rrType, rrClass, rrTTL, rrDNSIn);
            return rr;
        } catch (Exception ex) {
            throw new IOException("Unknown DNSAddressRR (type " + " (" + rrType + "))" + " Originating Exception: " + ex.getMessage());
        }
    }
}

DNSAddressRR.java

//
// This file is part of the OpenNMS(R) Application.
//
// OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc.  All rights reserved.
// OpenNMS(R) is a derivative work, containing both original code, included code and modified
// code that was published under the GNU General Public License. Copyrights for modified 
// and included code are below.
//
// OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
//
// Copyright (C) 1999-2001 Oculan Corp.  All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// For more information contact:
//      OpenNMS Licensing       <license@opennms.org>
//      http://www.opennms.org/
//      http://www.opennms.com/
//


import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * <P>
 * Holds a DNS resource record which is a DNS response that gives the IP address
 * of a particular hostname. A resource record typically has:
 * </P>
 * 
 * <TABLE BORDER=0>
 * <TH>
 * <TD>Element</TD>
 * <TD>Description</TD>
 * </TH>
 * <TR>
 * <TD>Name</TD>
 * <TD>Domain name that the resource record describes.</TD>
 * </TR>
 * <TR>
 * <TD>Type</TD>
 * <TD>Type of RR.</TD>
 * </TR>
 * <TR>
 * <TD>Class</TD>
 * <TD>RR Class.</TD>
 * </TR>
 * <TR>
 * <TD>TTL</TD>
 * <TD>Time-To-Live for the RR.</TD>
 * </TR>
 * <TR>
 * <TD>RDLEN</TD>
 * <TD>Length of the following data.</TD>
 * </TR>
 * <TR>
 * <TD>Data</TD>
 * <TD>Actual data of this RR.</TD>
 * </TR>
 * </TABLE>
 * 
 * @author <A HREF="mailto:sowmya@opennms.org">Sowmya </A>
 * @author <A HREF="http://www.opennms.org/">OpenNMS </A>
 * 
 */
public final class DNSAddressRR {
    /**
     * <P>
     * Name of this RR.
     * </P>
     */
    private String m_name;

    /**
     * <P>
     * Type of this RR.
     * </P>
     */
    private int m_type;

    /**
     * <P>
     * Class of this RR.
     * </P>
     */
    private int m_class;

    /**
     * <P>
     * Time to live for this RR.
     * </P>
     */
    private long m_TTL;

    /**
     * <P>
     * Time at which this RR was created.
     * </P>
     */
    private long m_created;

    /**
     * <P>
     * The IP Address for the Route Record.
     * </P>
     */
    private int[] ipAddress;

    /**
     * <P>
     * Returns the address in the dotted decimal format.
     * </P>
     * 
     * @return The address in the dotted decimal format.
     */
    private String AddressToByteString() {
        return ipAddress[0] + "." + ipAddress[1] + "." + ipAddress[2] + "." + ipAddress[3];
    }

    /**
     * <P>
     * Constructs an new DNS Address Resource Record with the specified
     * information.
     * </P>
     * 
     * @param name
     *            name of the RR
     * @param type
     *            type of the RR
     * @param clas
     *            class of the RR
     * @param ttl
     *            time for which this RR is valid
     * @param dnsIn
     *            inputstream for this RR
     * 
     * @exception java.io.IOException
     *                Thrown if an error occurs decoding data from the passed
     *                DNSInputStream.
     */
    public DNSAddressRR(String name, int type, int clas, long ttl, DNSInputStream dnsIn) throws IOException {
        m_name = name;
        m_type = type;
        m_class = clas;
        m_TTL = ttl;
        m_created = System.currentTimeMillis();

        // decode
        ipAddress = new int[4];
        for (int i = 0; i < 4; ++i) {
            ipAddress[i] = dnsIn.readByte();
        }
    }

    /**
     * <P>
     * Returns the address from the address record as a byte array.
     * </P>
     * 
     * @return The address as a byte array.
     */
    public byte[] getAddress() {
        byte[] ip = new byte[4];
        for (int j = 0; j < 4; j++)
            ip[j] = (byte) (ipAddress[j]);
        return ip;
    }

    /**
     * <P>
     * the InetAddress of the address contained for the record.
     * </P>
     * 
     * @return The InetAddress of the address
     * 
     * @exception java.net.UnknownHostException
     *                Thrown if the InetAddress object cannot be constructed.
     */
    public InetAddress getInetAddress() throws UnknownHostException {
        return InetAddress.getByName(AddressToByteString());
    }

    /**
     * <P>
     * Converts the object to a textual string that describes the resource
     * record.
     * </P>
     * 
     * @return The string describing the object.
     */
    public String toString() {
        return getRRName() + "	Internet Address = " + AddressToByteString();
    }

    /**
     * <P>
     * Returns the name of this RR.
     * </P>
     * 
     * @return The name of this RR.
     */
    public String getRRName() {
        return m_name;
    }

    /**
     * <P>
     * Returns the type of this RR.
     * </P>
     * 
     * @return The type of this RR.
     */
    public int getRRType() {
        return m_type;
    }

    /**
     * <P>
     * Returns the class of this RR.
     * </P>
     * 
     * @return The class of this RR.
     */
    public int getRRClass() {
        return m_class;
    }

    /**
     * <P>
     * Returns the TTL of this RR.
     * </P>
     * 
     * @return the TTL of this RR
     */
    public long getRRTTL() {
        return m_TTL;
    }

    /**
     * <P>
     * Returns true if still valid i.e. TTL has not expired.
     * </P>
     * 
     * @return True if valid, false if not.
     */
    public boolean isValid() {
        return m_TTL * 1000 > System.currentTimeMillis() - m_created;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值