2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2002 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: wks_11.c,v 1.51.18.1 2004/09/16 01:02:19 marka Exp $ */
20 /* Reviewed: Fri Mar 17 15:01:49 PST 2000 by explorer */
22 #ifndef RDATA_IN_1_WKS_11_C
23 #define RDATA_IN_1_WKS_11_C
29 #include <isc/netdb.h>
31 #define RRTYPE_WKS_ATTRIBUTES (0)
33 static inline isc_result_t
34 fromtext_in_wks(ARGS_FROMTEXT) {
42 unsigned char bm[8*1024]; /* 64k bits */
45 const char *ps = NULL;
51 REQUIRE(rdclass == 1);
61 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
64 isc_buffer_availableregion(target, ®ion);
65 if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
66 RETTOK(DNS_R_BADDOTTEDQUAD);
67 if (region.length < 4)
68 return (ISC_R_NOSPACE);
69 memcpy(region.base, &addr, 4);
70 isc_buffer_add(target, 4);
75 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
78 proto = strtol(DNS_AS_STR(token), &e, 10);
81 else if ((pe = getprotobyname(DNS_AS_STR(token))) != NULL)
84 RETTOK(DNS_R_UNKNOWNPROTO);
85 if (proto < 0 || proto > 0xff)
88 if (proto == IPPROTO_TCP)
90 else if (proto == IPPROTO_UDP)
93 RETERR(uint8_tobuffer(proto, target));
95 memset(bm, 0, sizeof(bm));
97 RETERR(isc_lex_getmastertoken(lexer, &token,
98 isc_tokentype_string, ISC_TRUE));
99 if (token.type != isc_tokentype_string)
103 * Lowercase the service string as some getservbyname() are
104 * case sensitive and the database is usually in lowercase.
106 strncpy(service, DNS_AS_STR(token), sizeof(service));
107 service[sizeof(service)-1] = '\0';
108 for (i = strlen(service) - 1; i >= 0; i--)
109 if (isupper(service[i]&0xff))
110 service[i] = tolower(service[i]&0xff);
112 port = strtol(DNS_AS_STR(token), &e, 10);
115 else if ((se = getservbyname(service, ps)) != NULL)
116 port = ntohs(se->s_port);
117 else if ((se = getservbyname(DNS_AS_STR(token), ps))
119 port = ntohs(se->s_port);
121 RETTOK(DNS_R_UNKNOWNSERVICE);
122 if (port < 0 || port > 0xffff)
126 bm[port / 8] |= (0x80 >> (port % 8));
130 * Let upper layer handle eol/eof.
132 isc_lex_ungettoken(lexer, &token);
134 n = (maxport + 8) / 8;
135 return (mem_tobuffer(target, bm, n));
138 static inline isc_result_t
139 totext_in_wks(ARGS_TOTEXT) {
141 unsigned short proto;
142 char buf[sizeof("65535")];
147 REQUIRE(rdata->type == 11);
148 REQUIRE(rdata->rdclass == 1);
149 REQUIRE(rdata->length >= 5);
151 dns_rdata_toregion(rdata, &sr);
152 RETERR(inet_totext(AF_INET, &sr, target));
153 isc_region_consume(&sr, 4);
155 proto = uint8_fromregion(&sr);
156 sprintf(buf, "%u", proto);
157 RETERR(str_totext(" ", target));
158 RETERR(str_totext(buf, target));
159 isc_region_consume(&sr, 1);
161 for (i = 0; i < sr.length; i++) {
163 for (j = 0; j < 8; j++)
164 if ((sr.base[i] & (0x80 >> j)) != 0) {
165 sprintf(buf, "%u", i * 8 + j);
166 RETERR(str_totext(" ", target));
167 RETERR(str_totext(buf, target));
171 return (ISC_R_SUCCESS);
174 static inline isc_result_t
175 fromwire_in_wks(ARGS_FROMWIRE) {
180 REQUIRE(rdclass == 1);
187 isc_buffer_activeregion(source, &sr);
188 isc_buffer_availableregion(target, &tr);
191 return (ISC_R_UNEXPECTEDEND);
192 if (sr.length > 8 * 1024 + 5)
193 return (DNS_R_EXTRADATA);
194 if (tr.length < sr.length)
195 return (ISC_R_NOSPACE);
197 memcpy(tr.base, sr.base, sr.length);
198 isc_buffer_add(target, sr.length);
199 isc_buffer_forward(source, sr.length);
201 return (ISC_R_SUCCESS);
204 static inline isc_result_t
205 towire_in_wks(ARGS_TOWIRE) {
210 REQUIRE(rdata->type == 11);
211 REQUIRE(rdata->rdclass == 1);
212 REQUIRE(rdata->length != 0);
214 dns_rdata_toregion(rdata, &sr);
215 return (mem_tobuffer(target, sr.base, sr.length));
219 compare_in_wks(ARGS_COMPARE) {
223 REQUIRE(rdata1->type == rdata2->type);
224 REQUIRE(rdata1->rdclass == rdata2->rdclass);
225 REQUIRE(rdata1->type == 11);
226 REQUIRE(rdata1->rdclass == 1);
227 REQUIRE(rdata1->length != 0);
228 REQUIRE(rdata2->length != 0);
230 dns_rdata_toregion(rdata1, &r1);
231 dns_rdata_toregion(rdata2, &r2);
232 return (isc_region_compare(&r1, &r2));
235 static inline isc_result_t
236 fromstruct_in_wks(ARGS_FROMSTRUCT) {
237 dns_rdata_in_wks_t *wks = source;
241 REQUIRE(rdclass == 1);
242 REQUIRE(source != NULL);
243 REQUIRE(wks->common.rdtype == type);
244 REQUIRE(wks->common.rdclass == rdclass);
245 REQUIRE(wks->map != NULL || wks->map_len == 0);
250 a = ntohl(wks->in_addr.s_addr);
251 RETERR(uint32_tobuffer(a, target));
252 RETERR(uint16_tobuffer(wks->protocol, target));
253 return (mem_tobuffer(target, wks->map, wks->map_len));
256 static inline isc_result_t
257 tostruct_in_wks(ARGS_TOSTRUCT) {
258 dns_rdata_in_wks_t *wks = target;
262 REQUIRE(rdata->type == 11);
263 REQUIRE(rdata->rdclass == 1);
264 REQUIRE(rdata->length != 0);
266 wks->common.rdclass = rdata->rdclass;
267 wks->common.rdtype = rdata->type;
268 ISC_LINK_INIT(&wks->common, link);
270 dns_rdata_toregion(rdata, ®ion);
271 n = uint32_fromregion(®ion);
272 wks->in_addr.s_addr = htonl(n);
273 isc_region_consume(®ion, 4);
274 wks->protocol = uint16_fromregion(®ion);
275 isc_region_consume(®ion, 2);
276 wks->map_len = region.length;
277 wks->map = mem_maybedup(mctx, region.base, region.length);
278 if (wks->map == NULL)
279 return (ISC_R_NOMEMORY);
281 return (ISC_R_SUCCESS);
285 freestruct_in_wks(ARGS_FREESTRUCT) {
286 dns_rdata_in_wks_t *wks = source;
288 REQUIRE(source != NULL);
289 REQUIRE(wks->common.rdtype == 11);
290 REQUIRE(wks->common.rdclass == 1);
292 if (wks->mctx == NULL)
295 if (wks->map != NULL)
296 isc_mem_free(wks->mctx, wks->map);
300 static inline isc_result_t
301 additionaldata_in_wks(ARGS_ADDLDATA) {
306 REQUIRE(rdata->type == 11);
307 REQUIRE(rdata->rdclass == 1);
309 return (ISC_R_SUCCESS);
312 static inline isc_result_t
313 digest_in_wks(ARGS_DIGEST) {
316 REQUIRE(rdata->type == 11);
317 REQUIRE(rdata->rdclass == 1);
319 dns_rdata_toregion(rdata, &r);
321 return ((digest)(arg, &r));
324 static inline isc_boolean_t
325 checkowner_in_wks(ARGS_CHECKOWNER) {
328 REQUIRE(rdclass == 1);
333 return (dns_name_ishostname(name, wildcard));
336 static inline isc_boolean_t
337 checknames_in_wks(ARGS_CHECKNAMES) {
339 REQUIRE(rdata->type == 11);
340 REQUIRE(rdata->rdclass == 1);
349 #endif /* RDATA_IN_1_WKS_11_C */