001: /*
002: * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.jndi.dns;
027:
028: import javax.naming.*;
029:
030: /**
031: * The Header class represents the header of a DNS message.
032: *
033: * @author Scott Seligman
034: * @version 1.12 07/05/05
035: */
036:
037: class Header {
038:
039: static final int HEADER_SIZE = 12; // octets in a DNS header
040:
041: // Masks and shift amounts for DNS header flag fields.
042: static final short QR_BIT = (short) 0x8000;
043: static final short OPCODE_MASK = (short) 0x7800;
044: static final int OPCODE_SHIFT = 11;
045: static final short AA_BIT = (short) 0x0400;
046: static final short TC_BIT = (short) 0x0200;
047: static final short RD_BIT = (short) 0x0100;
048: static final short RA_BIT = (short) 0x0080;
049: static final short RCODE_MASK = (short) 0x000F;
050:
051: int xid; // ID: 16-bit query identifier
052: boolean query; // QR: true if query, false if response
053: int opcode; // OPCODE: 4-bit opcode
054: boolean authoritative; // AA
055: boolean truncated; // TC
056: boolean recursionDesired; // RD
057: boolean recursionAvail; // RA
058: int rcode; // RCODE: 4-bit response code
059: int numQuestions;
060: int numAnswers;
061: int numAuthorities;
062: int numAdditionals;
063:
064: /*
065: * Returns a representation of a decoded DNS message header.
066: * Does not modify or store a reference to the msg array.
067: */
068: Header(byte[] msg, int msgLen) throws NamingException {
069: decode(msg, msgLen);
070: }
071:
072: /*
073: * Decodes a DNS message header. Does not modify or store a
074: * reference to the msg array.
075: */
076: private void decode(byte[] msg, int msgLen) throws NamingException {
077:
078: try {
079: int pos = 0; // current offset into msg
080:
081: if (msgLen < HEADER_SIZE) {
082: throw new CommunicationException(
083: "DNS error: corrupted message header");
084: }
085:
086: xid = getShort(msg, pos);
087: pos += 2;
088:
089: // Flags
090: short flags = (short) getShort(msg, pos);
091: pos += 2;
092: query = (flags & QR_BIT) == 0;
093: opcode = (flags & OPCODE_MASK) >>> OPCODE_SHIFT;
094: authoritative = (flags & AA_BIT) != 0;
095: truncated = (flags & TC_BIT) != 0;
096: recursionDesired = (flags & RD_BIT) != 0;
097: recursionAvail = (flags & RA_BIT) != 0;
098: rcode = (flags & RCODE_MASK);
099:
100: // RR counts
101: numQuestions = getShort(msg, pos);
102: pos += 2;
103: numAnswers = getShort(msg, pos);
104: pos += 2;
105: numAuthorities = getShort(msg, pos);
106: pos += 2;
107: numAdditionals = getShort(msg, pos);
108: pos += 2;
109:
110: } catch (IndexOutOfBoundsException e) {
111: throw new CommunicationException(
112: "DNS error: corrupted message header");
113: }
114: }
115:
116: /*
117: * Returns the 2-byte unsigned value at msg[pos]. The high
118: * order byte comes first.
119: */
120: private static int getShort(byte[] msg, int pos) {
121: return (((msg[pos] & 0xFF) << 8) | (msg[pos + 1] & 0xFF));
122: }
123: }
|