2 * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2002 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or 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.54.332.2 2009/02/16 23:47:15 tbox 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 INSIST(sr.length <= 8*1024);
162 for (i = 0; i < sr.length; i++) {
164 for (j = 0; j < 8; j++)
165 if ((sr.base[i] & (0x80 >> j)) != 0) {
166 sprintf(buf, "%u", i * 8 + j);
167 RETERR(str_totext(" ", target));
168 RETERR(str_totext(buf, target));
172 return (ISC_R_SUCCESS);
175 static inline isc_result_t
176 fromwire_in_wks(ARGS_FROMWIRE) {
181 REQUIRE(rdclass == 1);
188 isc_buffer_activeregion(source, &sr);
189 isc_buffer_availableregion(target, &tr);
192 return (ISC_R_UNEXPECTEDEND);
193 if (sr.length > 8 * 1024 + 5)
194 return (DNS_R_EXTRADATA);
195 if (tr.length < sr.length)
196 return (ISC_R_NOSPACE);
198 memcpy(tr.base, sr.base, sr.length);
199 isc_buffer_add(target, sr.length);
200 isc_buffer_forward(source, sr.length);
202 return (ISC_R_SUCCESS);
205 static inline isc_result_t
206 towire_in_wks(ARGS_TOWIRE) {
211 REQUIRE(rdata->type == 11);
212 REQUIRE(rdata->rdclass == 1);
213 REQUIRE(rdata->length != 0);
215 dns_rdata_toregion(rdata, &sr);
216 return (mem_tobuffer(target, sr.base, sr.length));
220 compare_in_wks(ARGS_COMPARE) {
224 REQUIRE(rdata1->type == rdata2->type);
225 REQUIRE(rdata1->rdclass == rdata2->rdclass);
226 REQUIRE(rdata1->type == 11);
227 REQUIRE(rdata1->rdclass == 1);
228 REQUIRE(rdata1->length != 0);
229 REQUIRE(rdata2->length != 0);
231 dns_rdata_toregion(rdata1, &r1);
232 dns_rdata_toregion(rdata2, &r2);
233 return (isc_region_compare(&r1, &r2));
236 static inline isc_result_t
237 fromstruct_in_wks(ARGS_FROMSTRUCT) {
238 dns_rdata_in_wks_t *wks = source;
242 REQUIRE(rdclass == 1);
243 REQUIRE(source != NULL);
244 REQUIRE(wks->common.rdtype == type);
245 REQUIRE(wks->common.rdclass == rdclass);
246 REQUIRE((wks->map != NULL && wks->map_len <= 8*1024) ||
252 a = ntohl(wks->in_addr.s_addr);
253 RETERR(uint32_tobuffer(a, target));
254 RETERR(uint16_tobuffer(wks->protocol, target));
255 return (mem_tobuffer(target, wks->map, wks->map_len));
258 static inline isc_result_t
259 tostruct_in_wks(ARGS_TOSTRUCT) {
260 dns_rdata_in_wks_t *wks = target;
264 REQUIRE(rdata->type == 11);
265 REQUIRE(rdata->rdclass == 1);
266 REQUIRE(rdata->length != 0);
268 wks->common.rdclass = rdata->rdclass;
269 wks->common.rdtype = rdata->type;
270 ISC_LINK_INIT(&wks->common, link);
272 dns_rdata_toregion(rdata, ®ion);
273 n = uint32_fromregion(®ion);
274 wks->in_addr.s_addr = htonl(n);
275 isc_region_consume(®ion, 4);
276 wks->protocol = uint16_fromregion(®ion);
277 isc_region_consume(®ion, 2);
278 wks->map_len = region.length;
279 wks->map = mem_maybedup(mctx, region.base, region.length);
280 if (wks->map == NULL)
281 return (ISC_R_NOMEMORY);
283 return (ISC_R_SUCCESS);
287 freestruct_in_wks(ARGS_FREESTRUCT) {
288 dns_rdata_in_wks_t *wks = source;
290 REQUIRE(source != NULL);
291 REQUIRE(wks->common.rdtype == 11);
292 REQUIRE(wks->common.rdclass == 1);
294 if (wks->mctx == NULL)
297 if (wks->map != NULL)
298 isc_mem_free(wks->mctx, wks->map);
302 static inline isc_result_t
303 additionaldata_in_wks(ARGS_ADDLDATA) {
308 REQUIRE(rdata->type == 11);
309 REQUIRE(rdata->rdclass == 1);
311 return (ISC_R_SUCCESS);
314 static inline isc_result_t
315 digest_in_wks(ARGS_DIGEST) {
318 REQUIRE(rdata->type == 11);
319 REQUIRE(rdata->rdclass == 1);
321 dns_rdata_toregion(rdata, &r);
323 return ((digest)(arg, &r));
326 static inline isc_boolean_t
327 checkowner_in_wks(ARGS_CHECKOWNER) {
330 REQUIRE(rdclass == 1);
335 return (dns_name_ishostname(name, wildcard));
338 static inline isc_boolean_t
339 checknames_in_wks(ARGS_CHECKNAMES) {
341 REQUIRE(rdata->type == 11);
342 REQUIRE(rdata->rdclass == 1);
351 #endif /* RDATA_IN_1_WKS_11_C */