1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* $Id: ipseckey_45.c,v 1.12 2020/02/26 18:47:59 florian Exp $ */
18 
19 #ifndef RDATA_GENERIC_IPSECKEY_45_C
20 #define RDATA_GENERIC_IPSECKEY_45_C
21 
22 #include <string.h>
23 
24 #include <isc/net.h>
25 
26 static inline isc_result_t
27 totext_ipseckey(ARGS_TOTEXT) {
28 	isc_region_t region;
29 	dns_name_t name;
30 	char buf[sizeof("255 ")];
31 	unsigned short num;
32 	unsigned short gateway;
33 
34 	REQUIRE(rdata->type == dns_rdatatype_ipseckey);
35 	REQUIRE(rdata->length >= 3);
36 
37 	dns_name_init(&name, NULL);
38 
39 	if (rdata->data[1] > 3U)
40 		return (ISC_R_NOTIMPLEMENTED);
41 
42 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
43 		RETERR(isc_str_tobuffer("( ", target));
44 
45 	/*
46 	 * Precedence.
47 	 */
48 	dns_rdata_toregion(rdata, &region);
49 	num = uint8_fromregion(&region);
50 	isc_region_consume(&region, 1);
51 	snprintf(buf, sizeof(buf), "%u ", num);
52 	RETERR(isc_str_tobuffer(buf, target));
53 
54 	/*
55 	 * Gateway type.
56 	 */
57 	gateway = uint8_fromregion(&region);
58 	isc_region_consume(&region, 1);
59 	snprintf(buf, sizeof(buf), "%u ", gateway);
60 	RETERR(isc_str_tobuffer(buf, target));
61 
62 	/*
63 	 * Algorithm.
64 	 */
65 	num = uint8_fromregion(&region);
66 	isc_region_consume(&region, 1);
67 	snprintf(buf, sizeof(buf), "%u ", num);
68 	RETERR(isc_str_tobuffer(buf, target));
69 
70 	/*
71 	 * Gateway.
72 	 */
73 	switch (gateway) {
74 	case 0:
75 		RETERR(isc_str_tobuffer(".", target));
76 		break;
77 
78 	case 1:
79 		RETERR(inet_totext(AF_INET, &region, target));
80 		isc_region_consume(&region, 4);
81 		break;
82 
83 	case 2:
84 		RETERR(inet_totext(AF_INET6, &region, target));
85 		isc_region_consume(&region, 16);
86 		break;
87 
88 	case 3:
89 		dns_name_fromregion(&name, &region);
90 		RETERR(dns_name_totext(&name, ISC_FALSE, target));
91 		isc_region_consume(&region, name_length(&name));
92 		break;
93 	}
94 
95 	/*
96 	 * Key.
97 	 */
98 	if (region.length > 0U) {
99 		RETERR(isc_str_tobuffer(tctx->linebreak, target));
100 		if (tctx->width == 0)   /* No splitting */
101 			RETERR(isc_base64_totext(&region, 60, "", target));
102 		else
103 			RETERR(isc_base64_totext(&region, tctx->width - 2,
104 						 tctx->linebreak, target));
105 	}
106 
107 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
108 		RETERR(isc_str_tobuffer(" )", target));
109 	return (ISC_R_SUCCESS);
110 }
111 
112 static inline isc_result_t
113 fromwire_ipseckey(ARGS_FROMWIRE) {
114 	dns_name_t name;
115 	isc_region_t region;
116 
117 	REQUIRE(type == dns_rdatatype_ipseckey);
118 
119 	UNUSED(type);
120 	UNUSED(rdclass);
121 
122 	dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
123 
124 	dns_name_init(&name, NULL);
125 
126 	isc_buffer_activeregion(source, &region);
127 	if (region.length < 3)
128 		return (ISC_R_UNEXPECTEDEND);
129 
130 	switch (region.base[1]) {
131 	case 0:
132 		isc_buffer_forward(source, region.length);
133 		return (isc_mem_tobuffer(target, region.base, region.length));
134 
135 	case 1:
136 		if (region.length < 7)
137 			return (ISC_R_UNEXPECTEDEND);
138 		isc_buffer_forward(source, region.length);
139 		return (isc_mem_tobuffer(target, region.base, region.length));
140 
141 	case 2:
142 		if (region.length < 19)
143 			return (ISC_R_UNEXPECTEDEND);
144 		isc_buffer_forward(source, region.length);
145 		return (isc_mem_tobuffer(target, region.base, region.length));
146 
147 	case 3:
148 		RETERR(isc_mem_tobuffer(target, region.base, 3));
149 		isc_buffer_forward(source, 3);
150 		RETERR(dns_name_fromwire(&name, source, dctx, options, target));
151 		isc_buffer_activeregion(source, &region);
152 		isc_buffer_forward(source, region.length);
153 		return(isc_mem_tobuffer(target, region.base, region.length));
154 
155 	default:
156 		return (ISC_R_NOTIMPLEMENTED);
157 	}
158 }
159 
160 static inline isc_result_t
161 towire_ipseckey(ARGS_TOWIRE) {
162 	isc_region_t region;
163 
164 	REQUIRE(rdata->type == dns_rdatatype_ipseckey);
165 	REQUIRE(rdata->length != 0);
166 
167 	UNUSED(cctx);
168 
169 	dns_rdata_toregion(rdata, &region);
170 	return (isc_mem_tobuffer(target, region.base, region.length));
171 }
172 
173 #endif	/* RDATA_GENERIC_IPSECKEY_45_C */
174