/* * Copyright 2015 The Netty Project * * The Netty Project licenses this file to you 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 io.netty.handler.codec.dns; import io.netty.channel.AddressedEnvelope; import io.netty.util.internal.StringUtil; import java.net.SocketAddress; /** * Provides some utility methods for DNS message implementations. */ final class DnsMessageUtil { static StringBuilder appendQuery(StringBuilder buf, DnsQuery query) { appendQueryHeader(buf, query); appendAllRecords(buf, query); return buf; } static StringBuilder appendResponse(StringBuilder buf, DnsResponse response) { appendResponseHeader(buf, response); appendAllRecords(buf, response); return buf; } static StringBuilder appendRecordClass(StringBuilder buf, int dnsClass) { final String name; switch (dnsClass &= 0xFFFF) { case DnsRecord.CLASS_IN: name = "IN"; break; case DnsRecord.CLASS_CSNET: name = "CSNET"; break; case DnsRecord.CLASS_CHAOS: name = "CHAOS"; break; case DnsRecord.CLASS_HESIOD: name = "HESIOD"; break; case DnsRecord.CLASS_NONE: name = "NONE"; break; case DnsRecord.CLASS_ANY: name = "ANY"; break; default: name = null; break; } if (name != null) { buf.append(name); } else { buf.append("UNKNOWN(").append(dnsClass).append(')'); } return buf; } private static void appendQueryHeader(StringBuilder buf, DnsQuery msg) { buf.append(StringUtil.simpleClassName(msg)) .append('('); appendAddresses(buf, msg) .append(msg.id()) .append(", ") .append(msg.opCode()); if (msg.isRecursionDesired()) { buf.append(", RD"); } if (msg.z() != 0) { buf.append(", Z: ") .append(msg.z()); } buf.append(')'); } private static void appendResponseHeader(StringBuilder buf, DnsResponse msg) { buf.append(StringUtil.simpleClassName(msg)) .append('('); appendAddresses(buf, msg) .append(msg.id()) .append(", ") .append(msg.opCode()) .append(", ") .append(msg.code()) .append(','); boolean hasComma = true; if (msg.isRecursionDesired()) { hasComma = false; buf.append(" RD"); } if (msg.isAuthoritativeAnswer()) { hasComma = false; buf.append(" AA"); } if (msg.isTruncated()) { hasComma = false; buf.append(" TC"); } if (msg.isRecursionAvailable()) { hasComma = false; buf.append(" RA"); } if (msg.z() != 0) { if (!hasComma) { buf.append(','); } buf.append(" Z: ") .append(msg.z()); } if (hasComma) { buf.setCharAt(buf.length() - 1, ')'); } else { buf.append(')'); } } private static StringBuilder appendAddresses(StringBuilder buf, DnsMessage msg) { if (!(msg instanceof AddressedEnvelope)) { return buf; } @SuppressWarnings("unchecked") AddressedEnvelope<?, SocketAddress> envelope = (AddressedEnvelope<?, SocketAddress>) msg; SocketAddress addr = envelope.sender(); if (addr != null) { buf.append("from: ") .append(addr) .append(", "); } addr = envelope.recipient(); if (addr != null) { buf.append("to: ") .append(addr) .append(", "); } return buf; } private static void appendAllRecords(StringBuilder buf, DnsMessage msg) { appendRecords(buf, msg, DnsSection.QUESTION); appendRecords(buf, msg, DnsSection.ANSWER); appendRecords(buf, msg, DnsSection.AUTHORITY); appendRecords(buf, msg, DnsSection.ADDITIONAL); } private static void appendRecords(StringBuilder buf, DnsMessage message, DnsSection section) { final int count = message.count(section); for (int i = 0; i < count; i ++) { buf.append(StringUtil.NEWLINE) .append(StringUtil.TAB) .append(message.<DnsRecord>recordAt(section, i)); } } private DnsMessageUtil() { } }