1// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5import java.io.*;
6import java.util.*;
7
8/**
9 * Next name - this record contains the following name in an ordered list
10 * of names in the zone, and a set of types for which records exist for
11 * this name.  The presence of this record in a response signifies a
12 * failed query for data in a DNSSEC-signed zone.
13 *
14 * @author Brian Wellington
15 */
16
17public class NXTRecord extends Record {
18
19private static final long serialVersionUID = -8851454400765507520L;
20
21private Name next;
22private BitSet bitmap;
23
24NXTRecord() {}
25
26Record
27getObject() {
28	return new NXTRecord();
29}
30
31/**
32 * Creates an NXT Record from the given data
33 * @param next The following name in an ordered list of the zone
34 * @param bitmap The set of type for which records exist at this name
35*/
36public
37NXTRecord(Name name, int dclass, long ttl, Name next, BitSet bitmap) {
38	super(name, Type.NXT, dclass, ttl);
39	this.next = checkName("next", next);
40	this.bitmap = bitmap;
41}
42
43void
44rrFromWire(DNSInput in) throws IOException {
45	next = new Name(in);
46	bitmap = new BitSet();
47	int bitmapLength = in.remaining();
48	for (int i = 0; i < bitmapLength; i++) {
49		int t = in.readU8();
50		for (int j = 0; j < 8; j++)
51			if ((t & (1 << (7 - j))) != 0)
52				bitmap.set(i * 8 + j);
53	}
54}
55
56void
57rdataFromString(Tokenizer st, Name origin) throws IOException {
58	next = st.getName(origin);
59	bitmap = new BitSet();
60	while (true) {
61		Tokenizer.Token t = st.get();
62		if (!t.isString())
63			break;
64		int typecode = Type.value(t.value, true);
65		if (typecode <= 0 || typecode > 128)
66			throw st.exception("Invalid type: " + t.value);
67		bitmap.set(typecode);
68	}
69	st.unget();
70}
71
72/** Converts rdata to a String */
73String
74rrToString() {
75	StringBuffer sb = new StringBuffer();
76	sb.append(next);
77	int length = bitmap.length();
78	for (short i = 0; i < length; i++)
79		if (bitmap.get(i)) {
80			sb.append(" ");
81			sb.append(Type.string(i));
82		}
83	return sb.toString();
84}
85
86/** Returns the next name */
87public Name
88getNext() {
89	return next;
90}
91
92/** Returns the set of types defined for this name */
93public BitSet
94getBitmap() {
95	return bitmap;
96}
97
98void
99rrToWire(DNSOutput out, Compression c, boolean canonical) {
100	next.toWire(out, null, canonical);
101	int length = bitmap.length();
102	for (int i = 0, t = 0; i < length; i++) {
103		t |= (bitmap.get(i) ? (1 << (7 - i % 8)) : 0);
104		if (i % 8 == 7 || i == length - 1) {
105			out.writeU8(t);
106			t = 0;
107		}
108	}
109}
110
111}
112