1// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5import java.io.*;
6import java.net.*;
7import org.xbill.DNS.utils.*;
8
9/**
10 * IPsec Keying Material (RFC 4025)
11 *
12 * @author Brian Wellington
13 */
14
15public class IPSECKEYRecord extends Record {
16
17private static final long serialVersionUID = 3050449702765909687L;
18
19public static class Algorithm {
20	private Algorithm() {}
21
22	public static final int DSA = 1;
23	public static final int RSA = 2;
24}
25
26public static class Gateway {
27	private Gateway() {}
28
29	public static final int None = 0;
30	public static final int IPv4 = 1;
31	public static final int IPv6 = 2;
32	public static final int Name = 3;
33}
34
35private int precedence;
36private int gatewayType;
37private int algorithmType;
38private Object gateway;
39private byte [] key;
40
41IPSECKEYRecord() {}
42
43Record
44getObject() {
45	return new IPSECKEYRecord();
46}
47
48/**
49 * Creates an IPSECKEY Record from the given data.
50 * @param precedence The record's precedence.
51 * @param gatewayType The record's gateway type.
52 * @param algorithmType The record's algorithm type.
53 * @param gateway The record's gateway.
54 * @param key The record's public key.
55 */
56public
57IPSECKEYRecord(Name name, int dclass, long ttl, int precedence,
58	       int gatewayType, int algorithmType, Object gateway,
59	       byte [] key)
60{
61	super(name, Type.IPSECKEY, dclass, ttl);
62	this.precedence = checkU8("precedence", precedence);
63	this.gatewayType = checkU8("gatewayType", gatewayType);
64	this.algorithmType = checkU8("algorithmType", algorithmType);
65	switch (gatewayType) {
66	case Gateway.None:
67		this.gateway = null;
68		break;
69	case Gateway.IPv4:
70		if (!(gateway instanceof InetAddress))
71			throw new IllegalArgumentException("\"gateway\" " +
72							   "must be an IPv4 " +
73							   "address");
74		this.gateway = gateway;
75		break;
76	case Gateway.IPv6:
77		if (!(gateway instanceof Inet6Address))
78			throw new IllegalArgumentException("\"gateway\" " +
79							   "must be an IPv6 " +
80							   "address");
81		this.gateway = gateway;
82		break;
83	case Gateway.Name:
84		if (!(gateway instanceof Name))
85			throw new IllegalArgumentException("\"gateway\" " +
86							   "must be a DNS " +
87							   "name");
88		this.gateway = checkName("gateway", (Name) gateway);
89		break;
90	default:
91		throw new IllegalArgumentException("\"gatewayType\" " +
92						   "must be between 0 and 3");
93	}
94
95	this.key = key;
96}
97
98void
99rrFromWire(DNSInput in) throws IOException {
100	precedence = in.readU8();
101	gatewayType = in.readU8();
102	algorithmType = in.readU8();
103	switch (gatewayType) {
104	case Gateway.None:
105		gateway = null;
106		break;
107	case Gateway.IPv4:
108		gateway = InetAddress.getByAddress(in.readByteArray(4));
109		break;
110	case Gateway.IPv6:
111		gateway = InetAddress.getByAddress(in.readByteArray(16));
112		break;
113	case Gateway.Name:
114		gateway = new Name(in);
115		break;
116	default:
117		throw new WireParseException("invalid gateway type");
118	}
119	if (in.remaining() > 0)
120		key = in.readByteArray();
121}
122
123void
124rdataFromString(Tokenizer st, Name origin) throws IOException {
125	precedence = st.getUInt8();
126	gatewayType = st.getUInt8();
127	algorithmType = st.getUInt8();
128	switch (gatewayType) {
129	case Gateway.None:
130		String s = st.getString();
131		if (!s.equals("."))
132			throw new TextParseException("invalid gateway format");
133		gateway = null;
134		break;
135	case Gateway.IPv4:
136		gateway = st.getAddress(Address.IPv4);
137		break;
138	case Gateway.IPv6:
139		gateway = st.getAddress(Address.IPv6);
140		break;
141	case Gateway.Name:
142		gateway = st.getName(origin);
143		break;
144	default:
145		throw new WireParseException("invalid gateway type");
146	}
147	key = st.getBase64(false);
148}
149
150String
151rrToString() {
152	StringBuffer sb = new StringBuffer();
153	sb.append(precedence);
154	sb.append(" ");
155	sb.append(gatewayType);
156	sb.append(" ");
157	sb.append(algorithmType);
158	sb.append(" ");
159	switch (gatewayType) {
160	case Gateway.None:
161		sb.append(".");
162		break;
163	case Gateway.IPv4:
164	case Gateway.IPv6:
165		InetAddress gatewayAddr = (InetAddress) gateway;
166		sb.append(gatewayAddr.getHostAddress());
167		break;
168	case Gateway.Name:
169		sb.append(gateway);
170		break;
171	}
172	if (key != null) {
173		sb.append(" ");
174		sb.append(base64.toString(key));
175	}
176	return sb.toString();
177}
178
179/** Returns the record's precedence. */
180public int
181getPrecedence() {
182	return precedence;
183}
184
185/** Returns the record's gateway type. */
186public int
187getGatewayType() {
188	return gatewayType;
189}
190
191/** Returns the record's algorithm type. */
192public int
193getAlgorithmType() {
194	return algorithmType;
195}
196
197/** Returns the record's gateway. */
198public Object
199getGateway() {
200	return gateway;
201}
202
203/** Returns the record's public key */
204public byte []
205getKey() {
206	return key;
207}
208
209void
210rrToWire(DNSOutput out, Compression c, boolean canonical) {
211	out.writeU8(precedence);
212	out.writeU8(gatewayType);
213	out.writeU8(algorithmType);
214	switch (gatewayType) {
215	case Gateway.None:
216		break;
217	case Gateway.IPv4:
218	case Gateway.IPv6:
219		InetAddress gatewayAddr = (InetAddress) gateway;
220		out.writeByteArray(gatewayAddr.getAddress());
221		break;
222	case Gateway.Name:
223		Name gatewayName = (Name) gateway;
224		gatewayName.toWire(out, null, canonical);
225		break;
226	}
227	if (key != null)
228		out.writeByteArray(key);
229}
230
231}
232