4 * Copyright (C) 2004, 2007, 2009 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.
20 /* Id: wks_11.c,v 1.57 2009/12/04 21:09:34 marka Exp */
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>
33 #define RRTYPE_WKS_ATTRIBUTES (0)
35 static inline isc_result_t
36 fromtext_in_wks(ARGS_FROMTEXT
) {
44 unsigned char bm
[8*1024]; /* 64k bits */
47 const char *ps
= NULL
;
53 REQUIRE(rdclass
== 1);
63 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
66 isc_buffer_availableregion(target
, ®ion
);
67 if (getquad(DNS_AS_STR(token
), &addr
, lexer
, callbacks
) != 1)
68 RETTOK(DNS_R_BADDOTTEDQUAD
);
69 if (region
.length
< 4)
70 return (ISC_R_NOSPACE
);
71 memcpy(region
.base
, &addr
, 4);
72 isc_buffer_add(target
, 4);
77 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
80 proto
= strtol(DNS_AS_STR(token
), &e
, 10);
83 else if ((pe
= getprotobyname(DNS_AS_STR(token
))) != NULL
)
86 RETTOK(DNS_R_UNKNOWNPROTO
);
87 if (proto
< 0 || proto
> 0xff)
90 if (proto
== IPPROTO_TCP
)
92 else if (proto
== IPPROTO_UDP
)
95 RETERR(uint8_tobuffer(proto
, target
));
97 memset(bm
, 0, sizeof(bm
));
99 RETERR(isc_lex_getmastertoken(lexer
, &token
,
100 isc_tokentype_string
, ISC_TRUE
));
101 if (token
.type
!= isc_tokentype_string
)
105 * Lowercase the service string as some getservbyname() are
106 * case sensitive and the database is usually in lowercase.
108 strncpy(service
, DNS_AS_STR(token
), sizeof(service
));
109 service
[sizeof(service
)-1] = '\0';
110 for (i
= strlen(service
) - 1; i
>= 0; i
--)
111 if (isupper(service
[i
]&0xff))
112 service
[i
] = tolower(service
[i
]&0xff);
114 port
= strtol(DNS_AS_STR(token
), &e
, 10);
117 else if ((se
= getservbyname(service
, ps
)) != NULL
)
118 port
= ntohs(se
->s_port
);
119 else if ((se
= getservbyname(DNS_AS_STR(token
), ps
))
121 port
= ntohs(se
->s_port
);
123 RETTOK(DNS_R_UNKNOWNSERVICE
);
124 if (port
< 0 || port
> 0xffff)
128 bm
[port
/ 8] |= (0x80 >> (port
% 8));
132 * Let upper layer handle eol/eof.
134 isc_lex_ungettoken(lexer
, &token
);
136 n
= (maxport
+ 8) / 8;
137 return (mem_tobuffer(target
, bm
, n
));
140 static inline isc_result_t
141 totext_in_wks(ARGS_TOTEXT
) {
143 unsigned short proto
;
144 char buf
[sizeof("65535")];
149 REQUIRE(rdata
->type
== 11);
150 REQUIRE(rdata
->rdclass
== 1);
151 REQUIRE(rdata
->length
>= 5);
153 dns_rdata_toregion(rdata
, &sr
);
154 RETERR(inet_totext(AF_INET
, &sr
, target
));
155 isc_region_consume(&sr
, 4);
157 proto
= uint8_fromregion(&sr
);
158 sprintf(buf
, "%u", proto
);
159 RETERR(str_totext(" ", target
));
160 RETERR(str_totext(buf
, target
));
161 isc_region_consume(&sr
, 1);
163 INSIST(sr
.length
<= 8*1024);
164 for (i
= 0; i
< sr
.length
; i
++) {
166 for (j
= 0; j
< 8; j
++)
167 if ((sr
.base
[i
] & (0x80 >> j
)) != 0) {
168 sprintf(buf
, "%u", i
* 8 + j
);
169 RETERR(str_totext(" ", target
));
170 RETERR(str_totext(buf
, target
));
174 return (ISC_R_SUCCESS
);
177 static inline isc_result_t
178 fromwire_in_wks(ARGS_FROMWIRE
) {
183 REQUIRE(rdclass
== 1);
190 isc_buffer_activeregion(source
, &sr
);
191 isc_buffer_availableregion(target
, &tr
);
194 return (ISC_R_UNEXPECTEDEND
);
195 if (sr
.length
> 8 * 1024 + 5)
196 return (DNS_R_EXTRADATA
);
197 if (tr
.length
< sr
.length
)
198 return (ISC_R_NOSPACE
);
200 memcpy(tr
.base
, sr
.base
, sr
.length
);
201 isc_buffer_add(target
, sr
.length
);
202 isc_buffer_forward(source
, sr
.length
);
204 return (ISC_R_SUCCESS
);
207 static inline isc_result_t
208 towire_in_wks(ARGS_TOWIRE
) {
213 REQUIRE(rdata
->type
== 11);
214 REQUIRE(rdata
->rdclass
== 1);
215 REQUIRE(rdata
->length
!= 0);
217 dns_rdata_toregion(rdata
, &sr
);
218 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
222 compare_in_wks(ARGS_COMPARE
) {
226 REQUIRE(rdata1
->type
== rdata2
->type
);
227 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
228 REQUIRE(rdata1
->type
== 11);
229 REQUIRE(rdata1
->rdclass
== 1);
230 REQUIRE(rdata1
->length
!= 0);
231 REQUIRE(rdata2
->length
!= 0);
233 dns_rdata_toregion(rdata1
, &r1
);
234 dns_rdata_toregion(rdata2
, &r2
);
235 return (isc_region_compare(&r1
, &r2
));
238 static inline isc_result_t
239 fromstruct_in_wks(ARGS_FROMSTRUCT
) {
240 dns_rdata_in_wks_t
*wks
= source
;
244 REQUIRE(rdclass
== 1);
245 REQUIRE(source
!= NULL
);
246 REQUIRE(wks
->common
.rdtype
== type
);
247 REQUIRE(wks
->common
.rdclass
== rdclass
);
248 REQUIRE((wks
->map
!= NULL
&& wks
->map_len
<= 8*1024) ||
254 a
= ntohl(wks
->in_addr
.s_addr
);
255 RETERR(uint32_tobuffer(a
, target
));
256 RETERR(uint16_tobuffer(wks
->protocol
, target
));
257 return (mem_tobuffer(target
, wks
->map
, wks
->map_len
));
260 static inline isc_result_t
261 tostruct_in_wks(ARGS_TOSTRUCT
) {
262 dns_rdata_in_wks_t
*wks
= target
;
266 REQUIRE(rdata
->type
== 11);
267 REQUIRE(rdata
->rdclass
== 1);
268 REQUIRE(rdata
->length
!= 0);
270 wks
->common
.rdclass
= rdata
->rdclass
;
271 wks
->common
.rdtype
= rdata
->type
;
272 ISC_LINK_INIT(&wks
->common
, link
);
274 dns_rdata_toregion(rdata
, ®ion
);
275 n
= uint32_fromregion(®ion
);
276 wks
->in_addr
.s_addr
= htonl(n
);
277 isc_region_consume(®ion
, 4);
278 wks
->protocol
= uint16_fromregion(®ion
);
279 isc_region_consume(®ion
, 2);
280 wks
->map_len
= region
.length
;
281 wks
->map
= mem_maybedup(mctx
, region
.base
, region
.length
);
282 if (wks
->map
== NULL
)
283 return (ISC_R_NOMEMORY
);
285 return (ISC_R_SUCCESS
);
289 freestruct_in_wks(ARGS_FREESTRUCT
) {
290 dns_rdata_in_wks_t
*wks
= source
;
292 REQUIRE(source
!= NULL
);
293 REQUIRE(wks
->common
.rdtype
== 11);
294 REQUIRE(wks
->common
.rdclass
== 1);
296 if (wks
->mctx
== NULL
)
299 if (wks
->map
!= NULL
)
300 isc_mem_free(wks
->mctx
, wks
->map
);
304 static inline isc_result_t
305 additionaldata_in_wks(ARGS_ADDLDATA
) {
310 REQUIRE(rdata
->type
== 11);
311 REQUIRE(rdata
->rdclass
== 1);
313 return (ISC_R_SUCCESS
);
316 static inline isc_result_t
317 digest_in_wks(ARGS_DIGEST
) {
320 REQUIRE(rdata
->type
== 11);
321 REQUIRE(rdata
->rdclass
== 1);
323 dns_rdata_toregion(rdata
, &r
);
325 return ((digest
)(arg
, &r
));
328 static inline isc_boolean_t
329 checkowner_in_wks(ARGS_CHECKOWNER
) {
332 REQUIRE(rdclass
== 1);
337 return (dns_name_ishostname(name
, wildcard
));
340 static inline isc_boolean_t
341 checknames_in_wks(ARGS_CHECKNAMES
) {
343 REQUIRE(rdata
->type
== 11);
344 REQUIRE(rdata
->rdclass
== 1);
354 casecompare_in_wks(ARGS_COMPARE
) {
355 return (compare_in_wks(rdata1
, rdata2
));
358 #endif /* RDATA_IN_1_WKS_11_C */