1 /* $NetBSD: wks_11.c,v 1.6 2014/12/10 04:37:59 christos Exp $ */
4 * Copyright (C) 2004, 2007, 2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
22 /* Reviewed: Fri Mar 17 15:01:49 PST 2000 by explorer */
24 #ifndef RDATA_IN_1_WKS_11_C
25 #define RDATA_IN_1_WKS_11_C
31 #include <isc/netdb.h>
34 #define RRTYPE_WKS_ATTRIBUTES (0)
36 static isc_mutex_t wks_lock
;
38 static void init_lock(void) {
39 RUNTIME_CHECK(isc_mutex_init(&wks_lock
) == ISC_R_SUCCESS
);
43 mygetprotobyname(const char *name
, long *proto
) {
47 pe
= getprotobyname(name
);
51 return (ISC_TF(pe
!= NULL
));
55 mygetservbyname(const char *name
, const char *proto
, long *port
) {
59 se
= getservbyname(name
, proto
);
61 *port
= ntohs(se
->s_port
);
63 return (ISC_TF(se
!= NULL
));
66 static inline isc_result_t
67 fromtext_in_wks(ARGS_FROMTEXT
) {
68 static isc_once_t once
= ISC_ONCE_INIT
;
74 unsigned char bm
[8*1024]; /* 64k bits */
77 const char *ps
= NULL
;
83 REQUIRE(rdclass
== 1);
90 RUNTIME_CHECK(isc_once_do(&once
, init_lock
) == ISC_R_SUCCESS
);
95 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
98 isc_buffer_availableregion(target
, ®ion
);
99 if (getquad(DNS_AS_STR(token
), &addr
, lexer
, callbacks
) != 1)
100 RETTOK(DNS_R_BADDOTTEDQUAD
);
101 if (region
.length
< 4)
102 return (ISC_R_NOSPACE
);
103 memmove(region
.base
, &addr
, 4);
104 isc_buffer_add(target
, 4);
109 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
112 proto
= strtol(DNS_AS_STR(token
), &e
, 10);
115 else if (!mygetprotobyname(DNS_AS_STR(token
), &proto
))
116 RETTOK(DNS_R_UNKNOWNPROTO
);
118 if (proto
< 0 || proto
> 0xff)
121 if (proto
== IPPROTO_TCP
)
123 else if (proto
== IPPROTO_UDP
)
126 RETERR(uint8_tobuffer(proto
, target
));
128 memset(bm
, 0, sizeof(bm
));
130 RETERR(isc_lex_getmastertoken(lexer
, &token
,
131 isc_tokentype_string
, ISC_TRUE
));
132 if (token
.type
!= isc_tokentype_string
)
136 * Lowercase the service string as some getservbyname() are
137 * case sensitive and the database is usually in lowercase.
139 strncpy(service
, DNS_AS_STR(token
), sizeof(service
));
140 service
[sizeof(service
)-1] = '\0';
141 for (i
= strlen(service
) - 1; i
>= 0; i
--)
142 if (isupper(service
[i
]&0xff))
143 service
[i
] = tolower(service
[i
]&0xff);
145 port
= strtol(DNS_AS_STR(token
), &e
, 10);
148 else if (!mygetservbyname(service
, ps
, &port
) &&
149 !mygetservbyname(DNS_AS_STR(token
), ps
, &port
))
150 RETTOK(DNS_R_UNKNOWNSERVICE
);
151 if (port
< 0 || port
> 0xffff)
155 bm
[port
/ 8] |= (0x80 >> (port
% 8));
159 * Let upper layer handle eol/eof.
161 isc_lex_ungettoken(lexer
, &token
);
163 n
= (maxport
+ 8) / 8;
164 return (mem_tobuffer(target
, bm
, n
));
167 static inline isc_result_t
168 totext_in_wks(ARGS_TOTEXT
) {
170 unsigned short proto
;
171 char buf
[sizeof("65535")];
176 REQUIRE(rdata
->type
== 11);
177 REQUIRE(rdata
->rdclass
== 1);
178 REQUIRE(rdata
->length
>= 5);
180 dns_rdata_toregion(rdata
, &sr
);
181 RETERR(inet_totext(AF_INET
, &sr
, target
));
182 isc_region_consume(&sr
, 4);
184 proto
= uint8_fromregion(&sr
);
185 sprintf(buf
, "%u", proto
);
186 RETERR(str_totext(" ", target
));
187 RETERR(str_totext(buf
, target
));
188 isc_region_consume(&sr
, 1);
190 INSIST(sr
.length
<= 8*1024);
191 for (i
= 0; i
< sr
.length
; i
++) {
193 for (j
= 0; j
< 8; j
++)
194 if ((sr
.base
[i
] & (0x80 >> j
)) != 0) {
195 sprintf(buf
, "%u", i
* 8 + j
);
196 RETERR(str_totext(" ", target
));
197 RETERR(str_totext(buf
, target
));
201 return (ISC_R_SUCCESS
);
204 static inline isc_result_t
205 fromwire_in_wks(ARGS_FROMWIRE
) {
210 REQUIRE(rdclass
== 1);
217 isc_buffer_activeregion(source
, &sr
);
218 isc_buffer_availableregion(target
, &tr
);
221 return (ISC_R_UNEXPECTEDEND
);
222 if (sr
.length
> 8 * 1024 + 5)
223 return (DNS_R_EXTRADATA
);
224 if (tr
.length
< sr
.length
)
225 return (ISC_R_NOSPACE
);
227 memmove(tr
.base
, sr
.base
, sr
.length
);
228 isc_buffer_add(target
, sr
.length
);
229 isc_buffer_forward(source
, sr
.length
);
231 return (ISC_R_SUCCESS
);
234 static inline isc_result_t
235 towire_in_wks(ARGS_TOWIRE
) {
240 REQUIRE(rdata
->type
== 11);
241 REQUIRE(rdata
->rdclass
== 1);
242 REQUIRE(rdata
->length
!= 0);
244 dns_rdata_toregion(rdata
, &sr
);
245 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
249 compare_in_wks(ARGS_COMPARE
) {
253 REQUIRE(rdata1
->type
== rdata2
->type
);
254 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
255 REQUIRE(rdata1
->type
== 11);
256 REQUIRE(rdata1
->rdclass
== 1);
257 REQUIRE(rdata1
->length
!= 0);
258 REQUIRE(rdata2
->length
!= 0);
260 dns_rdata_toregion(rdata1
, &r1
);
261 dns_rdata_toregion(rdata2
, &r2
);
262 return (isc_region_compare(&r1
, &r2
));
265 static inline isc_result_t
266 fromstruct_in_wks(ARGS_FROMSTRUCT
) {
267 dns_rdata_in_wks_t
*wks
= source
;
271 REQUIRE(rdclass
== 1);
272 REQUIRE(source
!= NULL
);
273 REQUIRE(wks
->common
.rdtype
== type
);
274 REQUIRE(wks
->common
.rdclass
== rdclass
);
275 REQUIRE((wks
->map
!= NULL
&& wks
->map_len
<= 8*1024) ||
281 a
= ntohl(wks
->in_addr
.s_addr
);
282 RETERR(uint32_tobuffer(a
, target
));
283 RETERR(uint8_tobuffer(wks
->protocol
, target
));
284 return (mem_tobuffer(target
, wks
->map
, wks
->map_len
));
287 static inline isc_result_t
288 tostruct_in_wks(ARGS_TOSTRUCT
) {
289 dns_rdata_in_wks_t
*wks
= target
;
293 REQUIRE(rdata
->type
== 11);
294 REQUIRE(rdata
->rdclass
== 1);
295 REQUIRE(rdata
->length
!= 0);
297 wks
->common
.rdclass
= rdata
->rdclass
;
298 wks
->common
.rdtype
= rdata
->type
;
299 ISC_LINK_INIT(&wks
->common
, link
);
301 dns_rdata_toregion(rdata
, ®ion
);
302 n
= uint32_fromregion(®ion
);
303 wks
->in_addr
.s_addr
= htonl(n
);
304 isc_region_consume(®ion
, 4);
305 wks
->protocol
= uint8_fromregion(®ion
);
306 isc_region_consume(®ion
, 1);
307 wks
->map_len
= region
.length
;
308 wks
->map
= mem_maybedup(mctx
, region
.base
, region
.length
);
309 if (wks
->map
== NULL
)
310 return (ISC_R_NOMEMORY
);
312 return (ISC_R_SUCCESS
);
316 freestruct_in_wks(ARGS_FREESTRUCT
) {
317 dns_rdata_in_wks_t
*wks
= source
;
319 REQUIRE(source
!= NULL
);
320 REQUIRE(wks
->common
.rdtype
== 11);
321 REQUIRE(wks
->common
.rdclass
== 1);
323 if (wks
->mctx
== NULL
)
326 if (wks
->map
!= NULL
)
327 isc_mem_free(wks
->mctx
, wks
->map
);
331 static inline isc_result_t
332 additionaldata_in_wks(ARGS_ADDLDATA
) {
337 REQUIRE(rdata
->type
== 11);
338 REQUIRE(rdata
->rdclass
== 1);
340 return (ISC_R_SUCCESS
);
343 static inline isc_result_t
344 digest_in_wks(ARGS_DIGEST
) {
347 REQUIRE(rdata
->type
== 11);
348 REQUIRE(rdata
->rdclass
== 1);
350 dns_rdata_toregion(rdata
, &r
);
352 return ((digest
)(arg
, &r
));
355 static inline isc_boolean_t
356 checkowner_in_wks(ARGS_CHECKOWNER
) {
359 REQUIRE(rdclass
== 1);
364 return (dns_name_ishostname(name
, wildcard
));
367 static inline isc_boolean_t
368 checknames_in_wks(ARGS_CHECKNAMES
) {
370 REQUIRE(rdata
->type
== 11);
371 REQUIRE(rdata
->rdclass
== 1);
381 casecompare_in_wks(ARGS_COMPARE
) {
382 return (compare_in_wks(rdata1
, rdata2
));
385 #endif /* RDATA_IN_1_WKS_11_C */