Author: erodriguez Date: Wed Jan 12 18:32:04 2005 New Revision: 125019 URL: http://svn.apache.org/viewcvs?view=rev&rev=125019 Log: DNS message encoder. Added: incubator/directory/dns/trunk/core/src/java/org/apache/dns/io/DnsMessageEncoder.java
Added: incubator/directory/dns/trunk/core/src/java/org/apache/dns/io/DnsMessageEncoder.java Url: http://svn.apache.org/viewcvs/incubator/directory/dns/trunk/core/src/java/org/apache/dns/io/DnsMessageEncoder.java?view=auto&rev=125019 ============================================================================== --- (empty file) +++ incubator/directory/dns/trunk/core/src/java/org/apache/dns/io/DnsMessageEncoder.java Wed Jan 12 18:32:04 2005 @@ -0,0 +1,158 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.dns.io; + +import java.nio.ByteBuffer; + +import org.apache.dns.messages.DnsMessage; +import org.apache.dns.messages.MessageType; +import org.apache.dns.messages.OpCode; +import org.apache.dns.messages.ResponseCode; +import org.apache.dns.records.QuestionRecord; +import org.apache.dns.records.ResourceRecord; + +public class DnsMessageEncoder +{ + public void encode( ByteBuffer byteBuffer, DnsMessage message ) + { + byteBuffer.putShort( message.getTransactionId() ); + + byte header = (byte)0x00; + header = encodeMessageType( message.getMessageType(), header ); + header = encodeOpCode( message.getOpCode(), header ); + header = encodeAuthoritativeAnswer( message.isAuthoritativeAnswer(), header ); + header = encodeTruncated( message.isTruncated(), header ); + header = encodeRecursionDesired( message.isRecursionDesired(), header ); + byteBuffer.put( header ); + + header = (byte)0x00; + header = encodeRecursionAvailable( message.isRecursionAvailable(), header ); + header = encodeResponseCode( message.getResponseCode(), header ); + byteBuffer.put( header ); + + byteBuffer.putShort( (short)message.getQuestionRecords().length ); + byteBuffer.putShort( (short)message.getAnswerRecords().length ); + byteBuffer.putShort( (short)message.getAuthorityRecords().length ); + byteBuffer.putShort( (short)message.getAdditionalRecords().length ); + + encodeQuestions( message.getQuestionRecords(), byteBuffer ); + encodeRecords( message.getAnswerRecords(), byteBuffer ); + encodeRecords( message.getAuthorityRecords(), byteBuffer ); + encodeRecords( message.getAdditionalRecords(), byteBuffer ); + } + + private void encodeRecords( ResourceRecord[] records, ByteBuffer byteBuffer ) + { + for ( int ii = 0; ii < records.length; ii++ ) + { + encodeDomainName( records[ ii ].getDomainName(), byteBuffer ); + + byteBuffer.putShort( (short)records[ ii ].getRecordType().getOrdinal() ); + byteBuffer.putShort( (short)records[ ii ].getRecordClass().getOrdinal() ); + + byteBuffer.putInt( records[ ii ].getTimeToLive() ); + byteBuffer.putShort( (short)records[ ii ].getResourceDataLength() ); + + records[ ii ].writeTo( byteBuffer ); + } + } + + private void encodeQuestions( QuestionRecord[] records, ByteBuffer byteBuffer ) + { + for ( int ii = 0; ii < records.length; ii++ ) + { + encodeDomainName( records[ ii ].getDomainName(), byteBuffer ); + + byteBuffer.putShort( (short)records[ ii ].getRecordType().getOrdinal() ); + byteBuffer.putShort( (short)records[ ii ].getRecordClass().getOrdinal() ); + } + } + + private void encodeDomainName( String domainName, ByteBuffer byteBuffer ) + { + String[] labels = domainName.split("\\."); + + for ( int ii = 0; ii < labels.length; ii++ ) + { + byteBuffer.put( (byte)labels[ ii ].length() ); + + char[] characters = labels[ ii ].toCharArray(); + for ( int jj = 0; jj < characters.length; jj++ ) + { + byteBuffer.put( (byte)characters[ jj ] ); + } + } + + byteBuffer.put( (byte)0x00 ); + } + + private byte encodeMessageType( MessageType messageType, byte header ) + { + byte oneBit = (byte)( messageType.getOrdinal() & 0x01 ); + return (byte)( ( oneBit << 7 ) | header ); + } + + private byte encodeOpCode( OpCode opCode, byte header ) + { + byte fourBits = (byte)( opCode.getOrdinal() & 0x0F ); + return (byte)( ( fourBits << 3 ) | header ); + } + + private byte encodeAuthoritativeAnswer( boolean authoritative, byte header ) + { + if ( authoritative ) + { + header = (byte)( ( (byte)0x01 << 2 ) | header ); + } + return header; + } + + private byte encodeTruncated( boolean truncated, byte header ) + { + if ( truncated ) + { + header = (byte)( ( (byte)0x01 << 1 ) | header ); + } + return header; + } + + private byte encodeRecursionDesired( boolean recursionDesired, byte header ) + { + if ( recursionDesired ) + { + header = (byte)( ( (byte)0x01 ) | header ); + } + return header; + } + + private byte encodeRecursionAvailable( boolean recursionAvailable, byte header ) + { + if ( recursionAvailable ) + { + header = (byte)( ( (byte)0x01 << 7 ) | header ); + } + return header; + } + + private byte encodeResponseCode( ResponseCode responseCode, byte header ) + { + byte fourBits = (byte)( responseCode.getOrdinal() & 0x0F ); + return (byte)( fourBits | header ); + } +} +
