dnsaddressrequest.java
来自「opennms得相关源码 请大家看看」· Java 代码 · 共 473 行
JAVA
473 行
//// 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///package org.opennms.protocols.dns;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.StringTokenizer;/** * <PRE> * * The DNSAddressRequest holds a DNS request to lookup the IP address of a host - * provides for transmitting and receiving the response for this lookup. * * NOTES: A DNS request and response has the following fileds header questions * answers authorities additional information * * The header has the following format: id - unique id sent by the client and * returned by the server in its response 16 bits of flags - * Query(0)/response(1) flag opcode - that has type of query AA - set if the * response is an authoritative answer TC - set if response is truncated RD - * set if recursion is desired RA - set if recursion is available Z - reserved * bits RCODE - response code * * This class checks only for the received response to have the answer(which * will hold the IP address) - ignores the authorities and additional info * * </PRE> * * @author <A HREF="mailto:sowmya@opennms.org">Sowmya </A> * @author <A HREF="http://www.opennms.org/">OpenNMS </A> * */public class DNSAddressRequest { /** * <P> * Defines the class internet in the domain name system. * </P> */ public final int CLASS_IN = 1; // internet /** * <P> * Defines the address type. * </P> */ public final int TYPE_ADDR = 1; // address /** * <P> * The offset of the query bit in the header. * </P> */ public final int SHIFT_QUERY = 15; /** * <P> * The offset of the opcode bits in the header. * </P> */ public final int SHIFT_OPCODE = 11; /** * <P> * The offset of the authoritative bit in the header. * </P> */ public final int SHIFT_AUTHORITATIVE = 10; /** * <P> * The offset of the truncated bit in the header. * </P> */ public final int SHIFT_TRUNCATED = 9; /** * <P> * The offset of the recurse req bit in the header. * </P> */ public final int SHIFT_RECURSE_PLEASE = 8; /** * <P> * The offset of the requrse avail bit in the header. * </P> */ public final int SHIFT_RECURSE_AVAILABLE = 7; /** * <P> * The offset of the reserved bits in the header. * </P> */ public final int SHIFT_RESERVED = 4; /** * <P> * The offset of the response code bits in the header. * </P> */ public final int SHIFT_RESPONSE_CODE = 0; /** * <P> * The op code for a query in the header. * </P> */ public final int OPCODE_QUERY = 0; /** * <P> * The host to request information from. This would be the nameserver if it * supports DNS. * </P> */ public String m_reqHost; /** * <P> * The id used to seralize the request. This allows the client (us) and the * server (host) to match exchanges. * </P> */ public int m_reqID; /** * <P> * True if the answer is authoratitve. * </P> */ public boolean m_authoritative; /** * <P> * True if the message is truncated. * </P> */ public boolean m_truncated; /** * <P> * True if the message is recursive. */ public boolean m_recursive; /** * <P> * The list of answers. * </P> */ public List m_answers; /** * <P> * The global id, used to get the request id. * </P> */ private static int globalID = 1; /** * <P> * Decodes the integer to get the flags - refer header for more info on the * flags. * </P> */ private void decodeFlags(int flags) throws IOException { // // check the response flag // boolean isResponse = ((flags >> SHIFT_QUERY) & 1) != 0; if (!isResponse) throw new IOException("Response flag not set"); // // check if error free // int code = (flags >> SHIFT_RESPONSE_CODE) & 15; if (code != 0) { if (code == 2) // Throw exception if error code indicates 'Server // Failure' throw new IOException(codeName(code) + " (" + code + ")"); } // // set the members of the instance. // m_authoritative = ((flags >> SHIFT_AUTHORITATIVE) & 1) != 0; m_truncated = ((flags >> SHIFT_TRUNCATED) & 1) != 0; m_recursive = ((flags >> SHIFT_RECURSE_AVAILABLE) & 1) != 0; } /** * <P> * Constructs a DNSAddressRequest for ths hostname passed. The host string * that is passed to the address string should be a hostname in "x.y.z" * where x, y, and z are strings. This is not suppose to be a dotted decimal * address. * </P> * * @param host * hostname for which address is to be constructed */ public DNSAddressRequest(String host) { // // Split the host into its component // parts. // StringTokenizer labels = new StringTokenizer(host, "."); while (labels.hasMoreTokens()) { // // if any section is longer than // 63 characters then it's illegal // if (labels.nextToken().length() > 63) throw new IllegalArgumentException("Invalid hostname: " + host); } // // The requested host // m_reqHost = host; // // Synchronize on the class, not // the instance. // synchronized (getClass()) { m_reqID = globalID % 65536; globalID = m_reqID + 1; // prevents negative numbers. } m_answers = new ArrayList(); } /** * <P> * Builds the address request. * </P> * * @return A byte array containing the request. */ public byte[] buildRequest() throws IOException { ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); DataOutputStream dataOut = new DataOutputStream(byteArrayOut); dataOut.writeShort(m_reqID); dataOut.writeShort((0 << SHIFT_QUERY) | (OPCODE_QUERY << SHIFT_OPCODE) | (1 << SHIFT_RECURSE_PLEASE)); dataOut.writeShort(1); // # queries dataOut.writeShort(0); // # answers dataOut.writeShort(0); // # authorities dataOut.writeShort(0); // # additional StringTokenizer labels = new StringTokenizer(m_reqHost, "."); while (labels.hasMoreTokens()) { String label = labels.nextToken(); dataOut.writeByte(label.length()); dataOut.writeBytes(label); } dataOut.writeByte(0); dataOut.writeShort(TYPE_ADDR); dataOut.writeShort(CLASS_IN); return byteArrayOut.toByteArray(); } /** * <P> * Extracts the response from the bytearray. * </P> * * @param data * The byte array containing the response. * @param length * The length of the byte array. * * @exception IOException * Thrown if there is an error while reading the recieved * packet */ public void receiveResponse(byte[] data, int length) throws IOException { /* * Decode the input stream. */ DNSInputStream dnsIn = new DNSInputStream(data, 0, length); int id = dnsIn.readShort(); if (id != m_reqID) throw new IOException("ID does not match request"); // // read in the flags // int flags = dnsIn.readShort(); decodeFlags(flags); int numQueries = dnsIn.readShort(); int numAnswers = dnsIn.readShort(); int numAuthorities = dnsIn.readShort(); int numAdditional = dnsIn.readShort(); while (numQueries-- > 0) { // // discard questions // String rname = dnsIn.readDomainName(); int rtype = dnsIn.readShort(); int rclass = dnsIn.readShort(); } try { while (numAnswers-- > 0) m_answers.add(dnsIn.readRR()); // ignore the authorities and additional information /** * while (numAuthorities -- > 0) dnsIn.readRR (); while * (numAdditional -- > 0) dnsIn.readRR (); */ } catch (IOException ex) { if (!m_truncated) throw ex; } } /** * <P> * This method only goes so far as to decode the flags in the response byte * array to verify that a DNS server sent the response. * </P> * * <P> * NOTE: This is really a hack to get around the fact that the * receiveResponse() method is not robust enough to handle all possible DNS * server responses. * * @param data * The byte array containing the response. * @param length * The length of the byte array. * * @exception IOException * Thrown if there is an error while reading the recieved * packet */ public void verifyResponse(byte[] data, int length) throws IOException { /* * Decode the input stream. */ DNSInputStream dnsIn = new DNSInputStream(data, 0, length); int id = dnsIn.readShort(); if (id != m_reqID) throw new IOException("ID does not match request"); // // read in the flags // int flags = dnsIn.readShort(); decodeFlags(flags); } /** * <P> * Return an enumeration of the recieved answers. * </P> * * @return The list of received answers. */ public List getAnswers() { return m_answers; } /** * <P> * The request id for this particular instance. * </P> */ public int getRequestID() { return m_reqID; } /** * <P> * The hostname that will be request from the DNS box. * </P> */ public String getHost() { return m_reqHost; } /** * <P> * Returns true if the answer is truncated. * </P> */ public boolean isTruncated() { return m_truncated; } /** * <P> * Returns true if the answer is recursive. * </P> */ public boolean isRecursive() { return m_recursive; } /** * <P> * Returns true if the answer is authoritative. * </P> */ public boolean isAuthoritative() { return m_authoritative; } /** * <P> * Returns the code string for the error code recieved. * </P> * * @param code * The error code. * * @return The error string corresponding to the error code */ public static String codeName(int code) { String[] codeNames = { "Format error", "Server failure", "Name not known", "Not implemented", "Refused" }; return ((code >= 1) && (code <= 5)) ? codeNames[code - 1] : "Unknown error"; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?