/* * Copyright 2012 Future Systems * * 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.krakenapps.dns; import java.nio.ByteBuffer; import java.util.StringTokenizer; public class DnsLabelCodec { private DnsLabelCodec() { } /** * parse domain name (label sequence) from dns message * * @param msg * whole dns message binary (including header) * @param offset * current label offset to parse * @return the label */ public static String decode(ByteBuffer bb) { boolean first = true; StringBuilder sb = new StringBuilder(); while (true) { /** * check msb 2 bit for decompression. label length is represented by * 6 bit, therefore max 64. */ byte b = bb.get(); if (b == 0) break; if ((b & 0xc0) != 0) { int nextOffset = b & 0x3f; b = bb.get(); nextOffset = (nextOffset << 8) | (b & 0xff); ByteBuffer dup = bb.duplicate(); dup.position(nextOffset); String prefix = sb.toString(); if (prefix.isEmpty()) return decode(dup); else return prefix + "." + decode(dup); } int len = b & 0x3f; byte[] label = new byte[len]; bb.get(label); if (first) first = false; else sb.append("."); sb.append(new String(label)); } return sb.toString(); } public static void encode(ByteBuffer bb, String domain) { // TODO: support message compression using label table parameter StringTokenizer tok = new StringTokenizer(domain, "."); while (tok.hasMoreTokens()) { byte[] label = tok.nextToken().getBytes(); if (label.length >= 64) throw new IllegalArgumentException("domain label length should be less than 64 bytes (see RFC)"); bb.put((byte) label.length); bb.put(label); } bb.put((byte) 0); } }