Bug Summary

File:src/usr.sbin/nsd/zonec.c
Warning:line 1256, column 19
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name zonec.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/nsd/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I . -I /usr/src/usr.sbin/nsd -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/nsd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/nsd/zonec.c
1/*
2 * zonec.c -- zone compiler.
3 *
4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5 *
6 * See LICENSE for the license.
7 *
8 */
9
10#include "config.h"
11
12#include <assert.h>
13#include <fcntl.h>
14#include <ctype.h>
15#include <errno(*__errno()).h>
16#include <limits.h>
17#include <stdio.h>
18#include <string.h>
19#ifdef HAVE_STRINGS_H1
20#include <strings.h>
21#endif
22#include <unistd.h>
23#include <stdlib.h>
24#include <time.h>
25#ifdef HAVE_SYS_STAT_H1
26#include <sys/stat.h>
27#endif
28
29#include <netinet/in.h>
30
31#ifdef HAVE_NETDB_H1
32#include <netdb.h>
33#endif
34
35#include "zonec.h"
36
37#include "dname.h"
38#include "dns.h"
39#include "namedb.h"
40#include "rdata.h"
41#include "region-allocator.h"
42#include "util.h"
43#include "zparser.h"
44#include "options.h"
45#include "nsec3.h"
46
47#define ILNP_MAXDIGITS4 4
48#define ILNP_NUMGROUPS4 4
49#define SVCB_MAX_COMMA_SEPARATED_VALUES1000 1000
50
51
52const dname_type *error_dname;
53domain_type *error_domain;
54
55static time_t startzonec = 0;
56static long int totalrrs = 0;
57
58extern uint8_t nsecbits[NSEC_WINDOW_COUNT256][NSEC_WINDOW_BITS_SIZE(256 / 8)];
59extern uint16_t nsec_highest_rcode;
60
61
62/*
63 * Allocate SIZE+sizeof(uint16_t) bytes and store SIZE in the first
64 * element. Return a pointer to the allocation.
65 */
66static uint16_t *
67alloc_rdata(region_type *region, size_t size)
68{
69 uint16_t *result = region_alloc(region, sizeof(uint16_t) + size);
70 *result = size;
71 return result;
72}
73
74uint16_t *
75alloc_rdata_init(region_type *region, const void *data, size_t size)
76{
77 uint16_t *result = region_alloc(region, sizeof(uint16_t) + size);
78 *result = size;
79 memcpy(result + 1, data, size);
80 return result;
81}
82
83/*
84 * These are parser function for generic zone file stuff.
85 */
86uint16_t *
87zparser_conv_hex(region_type *region, const char *hex, size_t len)
88{
89 /* convert a hex value to wireformat */
90 uint16_t *r = NULL((void *)0);
91 uint8_t *t;
92 int i;
93
94 if(len == 1 && hex[0] == '0') {
95 /* single 0 represents empty buffer */
96 return alloc_rdata(region, 0);
97 }
98 if (len % 2 != 0) {
99 zc_error_prev_line("number of hex digits must be a multiple of 2");
100 } else if (len > MAX_RDLENGTH65535 * 2) {
101 zc_error_prev_line("hex data exceeds maximum rdata length (%d)",
102 MAX_RDLENGTH65535);
103 } else {
104 /* the length part */
105 r = alloc_rdata(region, len/2);
106 t = (uint8_t *)(r + 1);
107
108 /* Now process octet by octet... */
109 while (*hex) {
110 *t = 0;
111 for (i = 16; i >= 1; i -= 15) {
112 if (isxdigit((unsigned char)*hex)) {
113 *t += hexdigit_to_int(*hex) * i;
114 } else {
115 zc_error_prev_line(
116 "illegal hex character '%c'",
117 (int) *hex);
118 return NULL((void *)0);
119 }
120 ++hex;
121 }
122 ++t;
123 }
124 }
125 return r;
126}
127
128/* convert hex, precede by a 1-byte length */
129uint16_t *
130zparser_conv_hex_length(region_type *region, const char *hex, size_t len)
131{
132 uint16_t *r = NULL((void *)0);
133 uint8_t *t;
134 int i;
135 if (len % 2 != 0) {
136 zc_error_prev_line("number of hex digits must be a multiple of 2");
137 } else if (len > 255 * 2) {
138 zc_error_prev_line("hex data exceeds 255 bytes");
139 } else {
140 uint8_t *l;
141
142 /* the length part */
143 r = alloc_rdata(region, len/2+1);
144 t = (uint8_t *)(r + 1);
145
146 l = t++;
147 *l = '\0';
148
149 /* Now process octet by octet... */
150 while (*hex) {
151 *t = 0;
152 for (i = 16; i >= 1; i -= 15) {
153 if (isxdigit((unsigned char)*hex)) {
154 *t += hexdigit_to_int(*hex) * i;
155 } else {
156 zc_error_prev_line(
157 "illegal hex character '%c'",
158 (int) *hex);
159 return NULL((void *)0);
160 }
161 ++hex;
162 }
163 ++t;
164 ++*l;
165 }
166 }
167 return r;
168}
169
170uint16_t *
171zparser_conv_time(region_type *region, const char *time)
172{
173 /* convert a time YYHM to wireformat */
174 uint16_t *r = NULL((void *)0);
175 struct tm tm;
176
177 /* Try to scan the time... */
178 if (!strptime(time, "%Y%m%d%H%M%S", &tm)) {
179 zc_error_prev_line("date and time is expected");
180 } else {
181 uint32_t l = htonl(mktime_from_utc(&tm))(__uint32_t)(__builtin_constant_p(mktime_from_utc(&tm)) ?
(__uint32_t)(((__uint32_t)(mktime_from_utc(&tm)) & 0xff
) << 24 | ((__uint32_t)(mktime_from_utc(&tm)) &
0xff00) << 8 | ((__uint32_t)(mktime_from_utc(&tm))
& 0xff0000) >> 8 | ((__uint32_t)(mktime_from_utc(&
tm)) & 0xff000000) >> 24) : __swap32md(mktime_from_utc
(&tm)))
;
182 r = alloc_rdata_init(region, &l, sizeof(l));
183 }
184 return r;
185}
186
187uint16_t *
188zparser_conv_services(region_type *region, const char *protostr,
189 char *servicestr)
190{
191 /*
192 * Convert a protocol and a list of service port numbers
193 * (separated by spaces) in the rdata to wireformat
194 */
195 uint16_t *r = NULL((void *)0);
196 uint8_t *p;
197 uint8_t bitmap[65536/8];
198 char sep[] = " ";
199 char *word;
200 int max_port = -8;
201 /* convert a protocol in the rdata to wireformat */
202 struct protoent *proto;
203
204 memset(bitmap, 0, sizeof(bitmap));
205
206 proto = getprotobyname(protostr);
207 if (!proto) {
208 proto = getprotobynumber(atoi(protostr));
209 }
210 if (!proto) {
211 zc_error_prev_line("unknown protocol '%s'", protostr);
212 return NULL((void *)0);
213 }
214
215 for (word = strtok(servicestr, sep); word; word = strtok(NULL((void *)0), sep)) {
216 struct servent *service;
217 int port;
218
219 service = getservbyname(word, proto->p_name);
220 if (service) {
221 /* Note: ntohs not ntohl! Strange but true. */
222 port = ntohs((uint16_t) service->s_port)(__uint16_t)(__builtin_constant_p((uint16_t) service->s_port
) ? (__uint16_t)(((__uint16_t)((uint16_t) service->s_port)
& 0xffU) << 8 | ((__uint16_t)((uint16_t) service->
s_port) & 0xff00U) >> 8) : __swap16md((uint16_t) service
->s_port))
;
223 } else {
224 char *end;
225 port = strtol(word, &end, 10);
226 if (*end != '\0') {
227 zc_error_prev_line("unknown service '%s' for protocol '%s'",
228 word, protostr);
229 continue;
230 }
231 }
232
233 if (port < 0 || port > 65535) {
234 zc_error_prev_line("bad port number %d", port);
235 } else {
236 set_bit(bitmap, port);
237 if (port > max_port)
238 max_port = port;
239 }
240 }
241
242 r = alloc_rdata(region, sizeof(uint8_t) + max_port / 8 + 1);
243 p = (uint8_t *) (r + 1);
244 *p = proto->p_proto;
245 memcpy(p + 1, bitmap, *r-1);
246
247 return r;
248}
249
250uint16_t *
251zparser_conv_serial(region_type *region, const char *serialstr)
252{
253 uint16_t *r = NULL((void *)0);
254 uint32_t serial;
255 const char *t;
256
257 serial = strtoserial(serialstr, &t);
258 if (*t != '\0') {
259 zc_error_prev_line("serial is expected or serial too big");
260 } else {
261 serial = htonl(serial)(__uint32_t)(__builtin_constant_p(serial) ? (__uint32_t)(((__uint32_t
)(serial) & 0xff) << 24 | ((__uint32_t)(serial) &
0xff00) << 8 | ((__uint32_t)(serial) & 0xff0000) >>
8 | ((__uint32_t)(serial) & 0xff000000) >> 24) : __swap32md
(serial))
;
262 r = alloc_rdata_init(region, &serial, sizeof(serial));
263 }
264 return r;
265}
266
267uint16_t *
268zparser_conv_period(region_type *region, const char *periodstr)
269{
270 /* convert a time period (think TTL's) to wireformat) */
271 uint16_t *r = NULL((void *)0);
272 uint32_t period;
273 const char *end;
274
275 /* Allocate required space... */
276 period = strtottl(periodstr, &end);
277 if (*end != '\0') {
278 zc_error_prev_line("time period is expected");
279 } else {
280 period = htonl(period)(__uint32_t)(__builtin_constant_p(period) ? (__uint32_t)(((__uint32_t
)(period) & 0xff) << 24 | ((__uint32_t)(period) &
0xff00) << 8 | ((__uint32_t)(period) & 0xff0000) >>
8 | ((__uint32_t)(period) & 0xff000000) >> 24) : __swap32md
(period))
;
281 r = alloc_rdata_init(region, &period, sizeof(period));
282 }
283 return r;
284}
285
286uint16_t *
287zparser_conv_short(region_type *region, const char *text)
288{
289 uint16_t *r = NULL((void *)0);
290 uint16_t value;
291 char *end;
292
293 value = htons((uint16_t) strtol(text, &end, 10))(__uint16_t)(__builtin_constant_p((uint16_t) strtol(text, &
end, 10)) ? (__uint16_t)(((__uint16_t)((uint16_t) strtol(text
, &end, 10)) & 0xffU) << 8 | ((__uint16_t)((uint16_t
) strtol(text, &end, 10)) & 0xff00U) >> 8) : __swap16md
((uint16_t) strtol(text, &end, 10)))
;
294 if (*end != '\0') {
295 zc_error_prev_line("integer value is expected");
296 } else {
297 r = alloc_rdata_init(region, &value, sizeof(value));
298 }
299 return r;
300}
301
302uint16_t *
303zparser_conv_byte(region_type *region, const char *text)
304{
305 uint16_t *r = NULL((void *)0);
306 uint8_t value;
307 char *end;
308
309 value = (uint8_t) strtol(text, &end, 10);
310 if (*end != '\0') {
311 zc_error_prev_line("integer value is expected");
312 } else {
313 r = alloc_rdata_init(region, &value, sizeof(value));
314 }
315 return r;
316}
317
318uint16_t *
319zparser_conv_algorithm(region_type *region, const char *text)
320{
321 const lookup_table_type *alg;
322 uint8_t id;
323
324 alg = lookup_by_name(dns_algorithms, text);
325 if (alg) {
326 id = (uint8_t) alg->id;
327 } else {
328 char *end;
329 id = (uint8_t) strtol(text, &end, 10);
330 if (*end != '\0') {
331 zc_error_prev_line("algorithm is expected");
332 return NULL((void *)0);
333 }
334 }
335
336 return alloc_rdata_init(region, &id, sizeof(id));
337}
338
339uint16_t *
340zparser_conv_certificate_type(region_type *region, const char *text)
341{
342 /* convert an algorithm string to integer */
343 const lookup_table_type *type;
344 uint16_t id;
345
346 type = lookup_by_name(dns_certificate_types, text);
347 if (type) {
348 id = htons((uint16_t) type->id)(__uint16_t)(__builtin_constant_p((uint16_t) type->id) ? (
__uint16_t)(((__uint16_t)((uint16_t) type->id) & 0xffU
) << 8 | ((__uint16_t)((uint16_t) type->id) & 0xff00U
) >> 8) : __swap16md((uint16_t) type->id))
;
349 } else {
350 char *end;
351 id = htons((uint16_t) strtol(text, &end, 10))(__uint16_t)(__builtin_constant_p((uint16_t) strtol(text, &
end, 10)) ? (__uint16_t)(((__uint16_t)((uint16_t) strtol(text
, &end, 10)) & 0xffU) << 8 | ((__uint16_t)((uint16_t
) strtol(text, &end, 10)) & 0xff00U) >> 8) : __swap16md
((uint16_t) strtol(text, &end, 10)))
;
352 if (*end != '\0') {
353 zc_error_prev_line("certificate type is expected");
354 return NULL((void *)0);
355 }
356 }
357
358 return alloc_rdata_init(region, &id, sizeof(id));
359}
360
361uint16_t *
362zparser_conv_a(region_type *region, const char *text)
363{
364 in_addr_t address;
365 uint16_t *r = NULL((void *)0);
366
367 if (inet_pton(AF_INET2, text, &address) != 1) {
368 zc_error_prev_line("invalid IPv4 address '%s'", text);
369 } else {
370 r = alloc_rdata_init(region, &address, sizeof(address));
371 }
372 return r;
373}
374
375uint16_t *
376zparser_conv_aaaa(region_type *region, const char *text)
377{
378 uint8_t address[IP6ADDRLEN(128/8)];
379 uint16_t *r = NULL((void *)0);
380
381 if (inet_pton(AF_INET624, text, address) != 1) {
382 zc_error_prev_line("invalid IPv6 address '%s'", text);
383 } else {
384 r = alloc_rdata_init(region, address, sizeof(address));
385 }
386 return r;
387}
388
389
390uint16_t *
391zparser_conv_ilnp64(region_type *region, const char *text)
392{
393 uint16_t *r = NULL((void *)0);
394 int ngroups, num;
395 unsigned long hex;
396 const char *ch;
397 char digits[ILNP_MAXDIGITS4+1];
398 unsigned int ui[ILNP_NUMGROUPS4];
399 uint16_t a[ILNP_NUMGROUPS4];
400
401 ngroups = 1; /* Always at least one group */
402 num = 0;
403 for (ch = text; *ch != '\0'; ch++) {
404 if (*ch == ':') {
405 if (num <= 0) {
406 zc_error_prev_line("ilnp64: empty group of "
407 "digits is not allowed");
408 return NULL((void *)0);
409 }
410 digits[num] = '\0';
411 hex = (unsigned long) strtol(digits, NULL((void *)0), 16);
412 num = 0;
413 ui[ngroups - 1] = hex;
414 if (ngroups >= ILNP_NUMGROUPS4) {
415 zc_error_prev_line("ilnp64: more than %d groups "
416 "of digits", ILNP_NUMGROUPS4);
417 return NULL((void *)0);
418 }
419 ngroups++;
420 } else {
421 /* Our grammar is stricter than the one accepted by
422 * strtol. */
423 if (!isxdigit((unsigned char)*ch)) {
424 zc_error_prev_line("ilnp64: invalid "
425 "(non-hexadecimal) character %c", *ch);
426 return NULL((void *)0);
427 }
428 if (num >= ILNP_MAXDIGITS4) {
429 zc_error_prev_line("ilnp64: more than %d digits "
430 "in a group", ILNP_MAXDIGITS4);
431 return NULL((void *)0);
432 }
433 digits[num++] = *ch;
434 }
435 }
436 if (num <= 0) {
437 zc_error_prev_line("ilnp64: empty group of digits is not "
438 "allowed");
439 return NULL((void *)0);
440 }
441 digits[num] = '\0';
442 hex = (unsigned long) strtol(digits, NULL((void *)0), 16);
443 ui[ngroups - 1] = hex;
444 if (ngroups < 4) {
445 zc_error_prev_line("ilnp64: less than %d groups of digits",
446 ILNP_NUMGROUPS4);
447 return NULL((void *)0);
448 }
449
450 a[0] = htons(ui[0])(__uint16_t)(__builtin_constant_p(ui[0]) ? (__uint16_t)(((__uint16_t
)(ui[0]) & 0xffU) << 8 | ((__uint16_t)(ui[0]) &
0xff00U) >> 8) : __swap16md(ui[0]))
;
451 a[1] = htons(ui[1])(__uint16_t)(__builtin_constant_p(ui[1]) ? (__uint16_t)(((__uint16_t
)(ui[1]) & 0xffU) << 8 | ((__uint16_t)(ui[1]) &
0xff00U) >> 8) : __swap16md(ui[1]))
;
452 a[2] = htons(ui[2])(__uint16_t)(__builtin_constant_p(ui[2]) ? (__uint16_t)(((__uint16_t
)(ui[2]) & 0xffU) << 8 | ((__uint16_t)(ui[2]) &
0xff00U) >> 8) : __swap16md(ui[2]))
;
453 a[3] = htons(ui[3])(__uint16_t)(__builtin_constant_p(ui[3]) ? (__uint16_t)(((__uint16_t
)(ui[3]) & 0xffU) << 8 | ((__uint16_t)(ui[3]) &
0xff00U) >> 8) : __swap16md(ui[3]))
;
454 r = alloc_rdata_init(region, a, sizeof(a));
455 return r;
456}
457
458static uint16_t *
459zparser_conv_eui48(region_type *region, const char *text)
460{
461 uint8_t nums[6];
462 uint16_t *r = NULL((void *)0);
463 unsigned int a, b, c, d, e, f;
464 int l;
465
466 if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x%n",
467 &a, &b, &c, &d, &e, &f, &l) != 6 ||
468 l != (int)strlen(text)){
469 zc_error_prev_line("eui48: invalid rr");
470 return NULL((void *)0);
471 }
472 nums[0] = (uint8_t)a;
473 nums[1] = (uint8_t)b;
474 nums[2] = (uint8_t)c;
475 nums[3] = (uint8_t)d;
476 nums[4] = (uint8_t)e;
477 nums[5] = (uint8_t)f;
478 r = alloc_rdata_init(region, nums, sizeof(nums));
479 return r;
480}
481
482static uint16_t *
483zparser_conv_eui64(region_type *region, const char *text)
484{
485 uint8_t nums[8];
486 uint16_t *r = NULL((void *)0);
487 unsigned int a, b, c, d, e, f, g, h;
488 int l;
489 if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n",
490 &a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 ||
491 l != (int)strlen(text)) {
492 zc_error_prev_line("eui64: invalid rr");
493 return NULL((void *)0);
494 }
495 nums[0] = (uint8_t)a;
496 nums[1] = (uint8_t)b;
497 nums[2] = (uint8_t)c;
498 nums[3] = (uint8_t)d;
499 nums[4] = (uint8_t)e;
500 nums[5] = (uint8_t)f;
501 nums[6] = (uint8_t)g;
502 nums[7] = (uint8_t)h;
503 r = alloc_rdata_init(region, nums, sizeof(nums));
504 return r;
505}
506
507uint16_t *
508zparser_conv_eui(region_type *region, const char *text, size_t len)
509{
510 uint16_t *r = NULL((void *)0);
511 int nnum, num;
512 const char* ch;
513
514 nnum = len/8;
515 num = 1;
516 for (ch = text; *ch != '\0'; ch++) {
517 if (*ch == '-') {
518 num++;
519 } else if (!isxdigit((unsigned char)*ch)) {
520 zc_error_prev_line("eui%u: invalid (non-hexadecimal) "
521 "character %c", (unsigned) len, *ch);
522 return NULL((void *)0);
523 }
524 }
525 if (num != nnum) {
526 zc_error_prev_line("eui%u: wrong number of hex numbers",
527 (unsigned) len);
528 return NULL((void *)0);
529 }
530
531 switch (len) {
532 case 48:
533 r = zparser_conv_eui48(region, text);
534 break;
535 case 64:
536 r = zparser_conv_eui64(region, text);
537 break;
538 default:
539 zc_error_prev_line("eui%u: invalid length",
540 (unsigned) len);
541 return NULL((void *)0);
542 break;
543 }
544 return r;
545}
546
547uint16_t *
548zparser_conv_text(region_type *region, const char *text, size_t len)
549{
550 uint16_t *r = NULL((void *)0);
551 uint8_t *p;
552
553 if (len > 255) {
554 zc_error_prev_line("text string is longer than 255 characters,"
555 " try splitting it into multiple parts");
556 len = 255;
557 }
558 r = alloc_rdata(region, len + 1);
559 p = (uint8_t *) (r + 1);
560 *p = len;
561 memcpy(p + 1, text, len);
562 return r;
563}
564
565/* for CAA Value [RFC 6844] */
566uint16_t *
567zparser_conv_long_text(region_type *region, const char *text, size_t len)
568{
569 uint16_t *r = NULL((void *)0);
570 if (len > MAX_RDLENGTH65535) {
571 zc_error_prev_line("text string is longer than max rdlen");
572 return NULL((void *)0);
573 }
574 r = alloc_rdata_init(region, text, len);
575 return r;
576}
577
578/* for CAA Tag [RFC 6844] */
579uint16_t *
580zparser_conv_tag(region_type *region, const char *text, size_t len)
581{
582 uint16_t *r = NULL((void *)0);
583 uint8_t *p;
584 const char* ptr;
585
586 if (len < 1) {
587 zc_error_prev_line("invalid tag: zero length");
588 return NULL((void *)0);
589 }
590 if (len > 15) {
591 zc_error_prev_line("invalid tag %s: longer than 15 characters (%u)",
592 text, (unsigned) len);
593 return NULL((void *)0);
594 }
595 for (ptr = text; *ptr; ptr++) {
596 if (!isdigit((unsigned char)*ptr) && !islower((unsigned char)*ptr)) {
597 zc_error_prev_line("invalid tag %s: contains invalid char %c",
598 text, *ptr);
599 return NULL((void *)0);
600 }
601 }
602 r = alloc_rdata(region, len + 1);
603 p = (uint8_t *) (r + 1);
604 *p = len;
605 memmove(p + 1, text, len);
606 return r;
607}
608
609uint16_t *
610zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len)
611{
612 uint16_t* r = NULL((void *)0);
613 uint8_t* p = NULL((void *)0);
614 r = alloc_rdata(region, len);
615 p = (uint8_t *) (r + 1);
616 memcpy(p, name, len);
617
618 return r;
619}
620
621uint16_t *
622zparser_conv_b32(region_type *region, const char *b32)
623{
624 uint8_t buffer[B64BUFSIZE65535];
625 uint16_t *r = NULL((void *)0);
626 int i;
627
628 if(strcmp(b32, "-") == 0) {
629 return alloc_rdata_init(region, "", 1);
630 }
631 i = b32_pton(b32, buffer+1, B64BUFSIZE65535-1);
632 if (i == -1 || i > 255) {
633 zc_error_prev_line("invalid base32 data");
634 } else {
635 buffer[0] = i; /* store length byte */
636 r = alloc_rdata_init(region, buffer, i+1);
637 }
638 return r;
639}
640
641uint16_t *
642zparser_conv_b64(region_type *region, const char *b64)
643{
644 uint8_t buffer[B64BUFSIZE65535];
645 uint16_t *r = NULL((void *)0);
646 int i;
647
648 if(strcmp(b64, "0") == 0) {
649 /* single 0 represents empty buffer */
650 return alloc_rdata(region, 0);
651 }
652 i = __b64_pton(b64, buffer, B64BUFSIZE65535);
653 if (i == -1) {
654 zc_error_prev_line("invalid base64 data");
655 } else {
656 r = alloc_rdata_init(region, buffer, i);
657 }
658 return r;
659}
660
661uint16_t *
662zparser_conv_rrtype(region_type *region, const char *text)
663{
664 uint16_t *r = NULL((void *)0);
665 uint16_t type = rrtype_from_string(text);
666
667 if (type == 0) {
668 zc_error_prev_line("unrecognized RR type '%s'", text);
669 } else {
670 type = htons(type)(__uint16_t)(__builtin_constant_p(type) ? (__uint16_t)(((__uint16_t
)(type) & 0xffU) << 8 | ((__uint16_t)(type) & 0xff00U
) >> 8) : __swap16md(type))
;
671 r = alloc_rdata_init(region, &type, sizeof(type));
672 }
673 return r;
674}
675
676uint16_t *
677zparser_conv_nxt(region_type *region, uint8_t nxtbits[])
678{
679 /* nxtbits[] consists of 16 bytes with some zero's in it
680 * copy every byte with zero to r and write the length in
681 * the first byte
682 */
683 uint16_t i;
684 uint16_t last = 0;
685
686 for (i = 0; i < 16; i++) {
687 if (nxtbits[i] != 0)
688 last = i + 1;
689 }
690
691 return alloc_rdata_init(region, nxtbits, last);
692}
693
694
695/* we potentially have 256 windows, each one is numbered. empty ones
696 * should be discarded
697 */
698uint16_t *
699zparser_conv_nsec(region_type *region,
700 uint8_t nsecbits[NSEC_WINDOW_COUNT256][NSEC_WINDOW_BITS_SIZE(256 / 8)])
701{
702 /* nsecbits contains up to 64K of bits which represent the
703 * types available for a name. Walk the bits according to
704 * nsec++ draft from jakob
705 */
706 uint16_t *r;
707 uint8_t *ptr;
708 size_t i,j;
709 uint16_t window_count = 0;
710 uint16_t total_size = 0;
711 uint16_t window_max = 0;
712
713 /* The used windows. */
714 int used[NSEC_WINDOW_COUNT256];
715 /* The last byte used in each the window. */
716 int size[NSEC_WINDOW_COUNT256];
717
718 window_max = 1 + (nsec_highest_rcode / 256);
719
720 /* used[i] is the i-th window included in the nsec
721 * size[used[0]] is the size of window 0
722 */
723
724 /* walk through the 256 windows */
725 for (i = 0; i < window_max; ++i) {
726 int empty_window = 1;
727 /* check each of the 32 bytes */
728 for (j = 0; j < NSEC_WINDOW_BITS_SIZE(256 / 8); ++j) {
729 if (nsecbits[i][j] != 0) {
730 size[i] = j + 1;
731 empty_window = 0;
732 }
733 }
734 if (!empty_window) {
735 used[window_count] = i;
736 window_count++;
737 }
738 }
739
740 for (i = 0; i < window_count; ++i) {
741 total_size += sizeof(uint16_t) + size[used[i]];
742 }
743
744 r = alloc_rdata(region, total_size);
745 ptr = (uint8_t *) (r + 1);
746
747 /* now walk used and copy it */
748 for (i = 0; i < window_count; ++i) {
749 ptr[0] = used[i];
750 ptr[1] = size[used[i]];
751 memcpy(ptr + 2, &nsecbits[used[i]], size[used[i]]);
752 ptr += size[used[i]] + 2;
753 }
754
755 return r;
756}
757
758static uint16_t
759svcbparam_lookup_key(const char *key, size_t key_len)
760{
761 char buf[64];
762 char *endptr;
763 unsigned long int key_value;
764
765 if (key_len >= 4 && key_len <= 8 && !strncmp(key, "key", 3)) {
766 memcpy(buf, key + 3, key_len - 3);
767 buf[key_len - 3] = 0;
768 key_value = strtoul(buf, &endptr, 10);
769 if (endptr > buf /* digits seen */
770 && *endptr == 0 /* no non-digit chars after digits */
771 && key_value <= 65535) /* no overflow */
772 return key_value;
773
774 } else switch (key_len) {
775 case sizeof("mandatory")-1:
776 if (!strncmp(key, "mandatory", sizeof("mandatory")-1))
777 return SVCB_KEY_MANDATORY0;
778 if (!strncmp(key, "echconfig", sizeof("echconfig")-1))
779 return SVCB_KEY_ECH5; /* allow "echconfig" as well as "ech" */
780 break;
781
782 case sizeof("alpn")-1:
783 if (!strncmp(key, "alpn", sizeof("alpn")-1))
784 return SVCB_KEY_ALPN1;
785 if (!strncmp(key, "port", sizeof("port")-1))
786 return SVCB_KEY_PORT3;
787 break;
788
789 case sizeof("no-default-alpn")-1:
790 if (!strncmp( key , "no-default-alpn"
791 , sizeof("no-default-alpn")-1))
792 return SVCB_KEY_NO_DEFAULT_ALPN2;
793 break;
794
795 case sizeof("ipv4hint")-1:
796 if (!strncmp(key, "ipv4hint", sizeof("ipv4hint")-1))
797 return SVCB_KEY_IPV4HINT4;
798 if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1))
799 return SVCB_KEY_IPV6HINT6;
800 break;
801 case sizeof("dohpath")-1:
802 if (!strncmp(key, "dohpath", sizeof("dohpath")-1))
803 return SVCB_KEY_DOHPATH7;
804 break;
805 case sizeof("ech")-1:
806 if (!strncmp(key, "ech", sizeof("ech")-1))
807 return SVCB_KEY_ECH5;
808 break;
809 default:
810 break;
811 }
812 if (key_len > sizeof(buf) - 1)
813 zc_error_prev_line("Unknown SvcParamKey");
814 else {
815 memcpy(buf, key, key_len);
816 buf[key_len] = 0;
817 zc_error_prev_line("Unknown SvcParamKey: %s", buf);
818 }
819 /* Although the returned value might be used by the caller,
820 * the parser has erred, so the zone will not be loaded.
821 */
822 return -1;
823}
824
825static uint16_t *
826zparser_conv_svcbparam_port_value(region_type *region, const char *val)
827{
828 unsigned long int port;
829 char *endptr;
830 uint16_t *r;
831
832 port = strtoul(val, &endptr, 10);
833 if (endptr > val /* digits seen */
834 && *endptr == 0 /* no non-digit chars after digits */
835 && port <= 65535) { /* no overflow */
836
837 r = alloc_rdata(region, 3 * sizeof(uint16_t));
838 r[1] = htons(SVCB_KEY_PORT)(__uint16_t)(__builtin_constant_p(3) ? (__uint16_t)(((__uint16_t
)(3) & 0xffU) << 8 | ((__uint16_t)(3) & 0xff00U
) >> 8) : __swap16md(3))
;
839 r[2] = htons(sizeof(uint16_t))(__uint16_t)(__builtin_constant_p(sizeof(uint16_t)) ? (__uint16_t
)(((__uint16_t)(sizeof(uint16_t)) & 0xffU) << 8 | (
(__uint16_t)(sizeof(uint16_t)) & 0xff00U) >> 8) : __swap16md
(sizeof(uint16_t)))
;
840 r[3] = htons(port)(__uint16_t)(__builtin_constant_p(port) ? (__uint16_t)(((__uint16_t
)(port) & 0xffU) << 8 | ((__uint16_t)(port) & 0xff00U
) >> 8) : __swap16md(port))
;
841 return r;
842 }
843 zc_error_prev_line("Could not parse port SvcParamValue: \"%s\"", val);
844 return NULL((void *)0);
845}
846
847static uint16_t *
848zparser_conv_svcbparam_ipv4hint_value(region_type *region, const char *val)
849{
850 uint16_t *r;
851 int count;
852 char ip_str[INET_ADDRSTRLEN16+1];
853 char *next_ip_str;
854 uint32_t *ip_wire_dst;
855 size_t i;
856
857 for (i = 0, count = 1; val[i]; i++) {
858 if (val[i] == ',')
859 count += 1;
860 if (count > SVCB_MAX_COMMA_SEPARATED_VALUES1000) {
861 zc_error_prev_line("Too many IPV4 addresses in ipv4hint");
862 return NULL((void *)0);
863 }
864 }
865
866 /* count == number of comma's in val + 1, so the actual number of IPv4
867 * addresses in val
868 */
869 r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP4ADDRLEN(32/8) * count);
870 r[1] = htons(SVCB_KEY_IPV4HINT)(__uint16_t)(__builtin_constant_p(4) ? (__uint16_t)(((__uint16_t
)(4) & 0xffU) << 8 | ((__uint16_t)(4) & 0xff00U
) >> 8) : __swap16md(4))
;
871 r[2] = htons(IP4ADDRLEN * count)(__uint16_t)(__builtin_constant_p((32/8) * count) ? (__uint16_t
)(((__uint16_t)((32/8) * count) & 0xffU) << 8 | ((__uint16_t
)((32/8) * count) & 0xff00U) >> 8) : __swap16md((32
/8) * count))
;
872 ip_wire_dst = (void *)&r[3];
873
874 while (count) {
875 if (!(next_ip_str = strchr(val, ','))) {
876 if (inet_pton(AF_INET2, val, ip_wire_dst) != 1)
877 break;
878
879 assert(count == 1)((void)0);
880
881 } else if (next_ip_str - val >= (int)sizeof(ip_str))
882 break;
883
884 else {
885 memcpy(ip_str, val, next_ip_str - val);
886 ip_str[next_ip_str - val] = 0;
887 if (inet_pton(AF_INET2, ip_str, ip_wire_dst) != 1) {
888 val = ip_str; /* to use in error reporting below */
889 break;
890 }
891
892 val = next_ip_str + 1;
893 }
894 ip_wire_dst++;
895 count--;
896 }
897 if (count)
898 zc_error_prev_line("Could not parse ipv4hint SvcParamValue: %s", val);
899
900 return r;
901}
902
903static uint16_t *
904zparser_conv_svcbparam_ipv6hint_value(region_type *region, const char *val)
905{
906 uint16_t *r;
907 int i, count;
908 char ip6_str[INET6_ADDRSTRLEN46+1];
909 char *next_ip6_str;
910 uint8_t *ipv6_wire_dst;
911
912 for (i = 0, count = 1; val[i]; i++) {
913 if (val[i] == ',')
914 count += 1;
915 if (count > SVCB_MAX_COMMA_SEPARATED_VALUES1000) {
916 zc_error_prev_line("Too many IPV6 addresses in ipv6hint");
917 return NULL((void *)0);
918 }
919 }
920
921 /* count == number of comma's in val + 1
922 * so actually the number of IPv6 addresses in val
923 */
924 r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP6ADDRLEN(128/8) * count);
925 r[1] = htons(SVCB_KEY_IPV6HINT)(__uint16_t)(__builtin_constant_p(6) ? (__uint16_t)(((__uint16_t
)(6) & 0xffU) << 8 | ((__uint16_t)(6) & 0xff00U
) >> 8) : __swap16md(6))
;
926 r[2] = htons(IP6ADDRLEN * count)(__uint16_t)(__builtin_constant_p((128/8) * count) ? (__uint16_t
)(((__uint16_t)((128/8) * count) & 0xffU) << 8 | ((
__uint16_t)((128/8) * count) & 0xff00U) >> 8) : __swap16md
((128/8) * count))
;
927 ipv6_wire_dst = (void *)&r[3];
928
929 while (count) {
930 if (!(next_ip6_str = strchr(val, ','))) {
931 if ((inet_pton(AF_INET624, val, ipv6_wire_dst) != 1))
932 break;
933
934 assert(count == 1)((void)0);
935
936 } else if (next_ip6_str - val >= (int)sizeof(ip6_str))
937 break;
938
939 else {
940 memcpy(ip6_str, val, next_ip6_str - val);
941 ip6_str[next_ip6_str - val] = 0;
942 if (inet_pton(AF_INET624, ip6_str, ipv6_wire_dst) != 1) {
943 val = ip6_str; /* for error reporting below */
944 break;
945 }
946
947 val = next_ip6_str + 1; /* skip the comma */
948 }
949 ipv6_wire_dst += IP6ADDRLEN(128/8);
950 count--;
951 }
952 if (count)
953 zc_error_prev_line("Could not parse ipv6hint SvcParamValue: %s", val);
954
955 return r;
956}
957
958static int
959network_uint16_cmp(const void *a, const void *b)
960{
961 return ((int)read_uint16(a)) - ((int)read_uint16(b));
962}
963
964static uint16_t *
965zparser_conv_svcbparam_mandatory_value(region_type *region,
966 const char *val, size_t val_len)
967{
968 uint16_t *r;
969 size_t i, count;
970 char* next_key;
971 uint16_t* key_dst;
972
973 for (i = 0, count = 1; val[i]; i++) {
974 if (val[i] == ',')
975 count += 1;
976 if (count > SVCB_MAX_COMMA_SEPARATED_VALUES1000) {
977 zc_error_prev_line("Too many keys in mandatory");
978 return NULL((void *)0);
979 }
980 }
981
982 r = alloc_rdata(region, (2 + count) * sizeof(uint16_t));
983 r[1] = htons(SVCB_KEY_MANDATORY)(__uint16_t)(__builtin_constant_p(0) ? (__uint16_t)(((__uint16_t
)(0) & 0xffU) << 8 | ((__uint16_t)(0) & 0xff00U
) >> 8) : __swap16md(0))
;
984 r[2] = htons(sizeof(uint16_t) * count)(__uint16_t)(__builtin_constant_p(sizeof(uint16_t) * count) ?
(__uint16_t)(((__uint16_t)(sizeof(uint16_t) * count) & 0xffU
) << 8 | ((__uint16_t)(sizeof(uint16_t) * count) & 0xff00U
) >> 8) : __swap16md(sizeof(uint16_t) * count))
;
985 key_dst = (void *)&r[3];
986
987 for(;;) {
988 if (!(next_key = strchr(val, ','))) {
989 *key_dst = htons(svcbparam_lookup_key(val, val_len))(__uint16_t)(__builtin_constant_p(svcbparam_lookup_key(val, val_len
)) ? (__uint16_t)(((__uint16_t)(svcbparam_lookup_key(val, val_len
)) & 0xffU) << 8 | ((__uint16_t)(svcbparam_lookup_key
(val, val_len)) & 0xff00U) >> 8) : __swap16md(svcbparam_lookup_key
(val, val_len)))
;
990 break;
991 } else {
992 *key_dst = htons(svcbparam_lookup_key(val, next_key - val))(__uint16_t)(__builtin_constant_p(svcbparam_lookup_key(val, next_key
- val)) ? (__uint16_t)(((__uint16_t)(svcbparam_lookup_key(val
, next_key - val)) & 0xffU) << 8 | ((__uint16_t)(svcbparam_lookup_key
(val, next_key - val)) & 0xff00U) >> 8) : __swap16md
(svcbparam_lookup_key(val, next_key - val)))
;
993 }
994
995 val_len -= next_key - val + 1;
996 val = next_key + 1; /* skip the comma */
997 key_dst += 1;
998 }
999
1000 /* In draft-ietf-dnsop-svcb-https-04 Section 7:
1001 *
1002 * In wire format, the keys are represented by their numeric
1003 * values in network byte order, concatenated in ascending order.
1004 */
1005 qsort((void *)&r[3], count, sizeof(uint16_t), network_uint16_cmp);
1006
1007 return r;
1008}
1009
1010static uint16_t *
1011zparser_conv_svcbparam_ech_value(region_type *region, const char *b64)
1012{
1013 uint8_t buffer[B64BUFSIZE65535];
1014 uint16_t *r = NULL((void *)0);
1015 int wire_len;
1016
1017 if(strcmp(b64, "0") == 0) {
1018 /* single 0 represents empty buffer */
1019 return alloc_rdata(region, 0);
1020 }
1021 wire_len = __b64_pton(b64, buffer, B64BUFSIZE65535);
1022 if (wire_len == -1) {
1023 zc_error_prev_line("invalid base64 data in ech");
1024 } else {
1025 r = alloc_rdata(region, 2 * sizeof(uint16_t) + wire_len);
1026 r[1] = htons(SVCB_KEY_ECH)(__uint16_t)(__builtin_constant_p(5) ? (__uint16_t)(((__uint16_t
)(5) & 0xffU) << 8 | ((__uint16_t)(5) & 0xff00U
) >> 8) : __swap16md(5))
;
1027 r[2] = htons(wire_len)(__uint16_t)(__builtin_constant_p(wire_len) ? (__uint16_t)(((
__uint16_t)(wire_len) & 0xffU) << 8 | ((__uint16_t)
(wire_len) & 0xff00U) >> 8) : __swap16md(wire_len))
;
1028 memcpy(&r[3], buffer, wire_len);
1029 }
1030
1031 return r;
1032}
1033
1034static const char* parse_alpn_next_unescaped_comma(const char *val)
1035{
1036 while (*val) {
1037 /* Only return when the comma is not escaped*/
1038 if (*val == '\\'){
1039 ++val;
1040 if (!*val)
1041 break;
1042 } else if (*val == ',')
1043 return val;
1044
1045 val++;
1046 }
1047 return NULL((void *)0);
1048}
1049
1050static size_t
1051parse_alpn_copy_unescaped(uint8_t *dst, const char *src, size_t len)
1052{
1053 uint8_t *orig_dst = dst;
1054
1055 while (len) {
1056 if (*src == '\\') {
1057 src++;
1058 len--;
1059 if (!len)
1060 break;
1061 }
1062 *dst++ = *src++;
1063 len--;
1064 }
1065 return (size_t)(dst - orig_dst);
1066}
1067
1068static uint16_t *
1069zparser_conv_svcbparam_alpn_value(region_type *region,
1070 const char *val, size_t val_len)
1071{
1072 uint8_t unescaped_dst[65536];
1073 uint8_t *dst = unescaped_dst;
1074 const char *next_str;
1075 size_t str_len;
1076 size_t dst_len;
1077 uint16_t *r = NULL((void *)0);
1078
1079 if (val_len > sizeof(unescaped_dst)) {
1080 zc_error_prev_line("invalid alpn");
1081 return r;
1082 }
1083 while (val_len) {
1084 size_t dst_len;
1085
1086 str_len = (next_str = parse_alpn_next_unescaped_comma(val))
1087 ? (size_t)(next_str - val) : val_len;
1088
1089 if (str_len > 255) {
1090 zc_error_prev_line("alpn strings need to be"
1091 " smaller than 255 chars");
1092 return r;
1093 }
1094 dst_len = parse_alpn_copy_unescaped(dst + 1, val, str_len);
1095 *dst++ = dst_len;
1096 dst += dst_len;
1097
1098 if (!next_str)
1099 break;
1100
1101 /* skip the comma for the next iteration */
1102 val_len -= next_str - val + 1;
1103 val = next_str + 1;
1104 }
1105 dst_len = dst - unescaped_dst;
1106 r = alloc_rdata(region, 2 * sizeof(uint16_t) + dst_len);
1107 r[1] = htons(SVCB_KEY_ALPN)(__uint16_t)(__builtin_constant_p(1) ? (__uint16_t)(((__uint16_t
)(1) & 0xffU) << 8 | ((__uint16_t)(1) & 0xff00U
) >> 8) : __swap16md(1))
;
1108 r[2] = htons(dst_len)(__uint16_t)(__builtin_constant_p(dst_len) ? (__uint16_t)(((__uint16_t
)(dst_len) & 0xffU) << 8 | ((__uint16_t)(dst_len) &
0xff00U) >> 8) : __swap16md(dst_len))
;
1109 memcpy(&r[3], unescaped_dst, dst_len);
1110 return r;
1111}
1112
1113static uint16_t *
1114zparser_conv_svcbparam_key_value(region_type *region,
1115 const char *key, size_t key_len, const char *val, size_t val_len)
1116{
1117 uint16_t svcparamkey = svcbparam_lookup_key(key, key_len);
1118 uint16_t *r;
1119
1120 switch (svcparamkey) {
1121 case SVCB_KEY_PORT3:
1122 return zparser_conv_svcbparam_port_value(region, val);
1123 case SVCB_KEY_IPV4HINT4:
1124 return zparser_conv_svcbparam_ipv4hint_value(region, val);
1125 case SVCB_KEY_IPV6HINT6:
1126 return zparser_conv_svcbparam_ipv6hint_value(region, val);
1127 case SVCB_KEY_MANDATORY0:
1128 return zparser_conv_svcbparam_mandatory_value(region, val, val_len);
1129 case SVCB_KEY_NO_DEFAULT_ALPN2:
1130 if(zone_is_slave(parser->current_zone->opts))
1131 zc_warning_prev_line("no-default-alpn should not have a value");
1132 else
1133 zc_error_prev_line("no-default-alpn should not have a value");
1134 break;
1135 case SVCB_KEY_ECH5:
1136 return zparser_conv_svcbparam_ech_value(region, val);
1137 case SVCB_KEY_ALPN1:
1138 return zparser_conv_svcbparam_alpn_value(region, val, val_len);
1139 case SVCB_KEY_DOHPATH7:
1140 /* fallthrough */
1141 default:
1142 break;
1143 }
1144 r = alloc_rdata(region, 2 * sizeof(uint16_t) + val_len);
1145 r[1] = htons(svcparamkey)(__uint16_t)(__builtin_constant_p(svcparamkey) ? (__uint16_t)
(((__uint16_t)(svcparamkey) & 0xffU) << 8 | ((__uint16_t
)(svcparamkey) & 0xff00U) >> 8) : __swap16md(svcparamkey
))
;
1146 r[2] = htons(val_len)(__uint16_t)(__builtin_constant_p(val_len) ? (__uint16_t)(((__uint16_t
)(val_len) & 0xffU) << 8 | ((__uint16_t)(val_len) &
0xff00U) >> 8) : __swap16md(val_len))
;
1147 memcpy(r + 3, val, val_len);
1148 return r;
1149}
1150
1151uint16_t *
1152zparser_conv_svcbparam(region_type *region, const char *key, size_t key_len
1153 , const char *val, size_t val_len)
1154{
1155 const char *eq;
1156 uint16_t *r;
1157 uint16_t svcparamkey;
1158
1159 /* Form <key>="<value>" (or at least with quoted value) */
1160 if (val && val_len) {
1161 /* Does key end with '=' */
1162 if (key_len && key[key_len - 1] == '=')
1163 return zparser_conv_svcbparam_key_value(
1164 region, key, key_len - 1, val, val_len);
1165
1166 zc_error_prev_line( "SvcParam syntax error in param: %s\"%s\""
1167 , key, val);
1168 }
1169 assert(val == NULL)((void)0);
1170 if ((eq = memchr(key, '=', key_len))) {
1171 size_t new_key_len = eq - key;
1172
1173 if (key_len - new_key_len - 1 > 0)
1174 return zparser_conv_svcbparam_key_value(region,
1175 key, new_key_len, eq+1, key_len - new_key_len - 1);
1176 key_len = new_key_len;
1177 }
1178 /* Some SvcParamKeys require values */
1179 svcparamkey = svcbparam_lookup_key(key, key_len);
1180 switch (svcparamkey) {
1181 case SVCB_KEY_MANDATORY0:
1182 case SVCB_KEY_ALPN1:
1183 case SVCB_KEY_PORT3:
1184 case SVCB_KEY_IPV4HINT4:
1185 case SVCB_KEY_IPV6HINT6:
1186 case SVCB_KEY_DOHPATH7:
1187 if(zone_is_slave(parser->current_zone->opts))
1188 zc_warning_prev_line("value expected for SvcParam: %s", key);
1189 else
1190 zc_error_prev_line("value expected for SvcParam: %s", key);
1191 break;
1192 default:
1193 break;
1194 }
1195 /* SvcParam is only a SvcParamKey */
1196 r = alloc_rdata(region, 2 * sizeof(uint16_t));
1197 r[1] = htons(svcparamkey)(__uint16_t)(__builtin_constant_p(svcparamkey) ? (__uint16_t)
(((__uint16_t)(svcparamkey) & 0xffU) << 8 | ((__uint16_t
)(svcparamkey) & 0xff00U) >> 8) : __swap16md(svcparamkey
))
;
1198 r[2] = 0;
1199 return r;
1200}
1201
1202/* Parse an int terminated in the specified range. */
1203static int
1204parse_int(const char *str,
1205 char **end,
1206 int *result,
1207 const char *name,
1208 int min,
1209 int max)
1210{
1211 *result = (int) strtol(str, end, 10);
1212 if (*result < min || *result > max) {
1213 zc_error_prev_line("%s must be within the range [%d .. %d]",
1214 name,
1215 min,
1216 max);
1217 return 0;
1218 } else {
1219 return 1;
1220 }
1221}
1222
1223/* RFC1876 conversion routines */
1224static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1225 1000000,10000000,100000000,1000000000};
1226
1227/*
1228 * Converts ascii size/precision X * 10**Y(cm) to 0xXY.
1229 * Sets the given pointer to the last used character.
1230 *
1231 */
1232static uint8_t
1233precsize_aton (char *cp, char **endptr)
1234{
1235 unsigned int mval = 0, cmval = 0;
1236 uint8_t retval = 0;
1237 int exponent;
1238 int mantissa;
1239
1240 while (isdigit((unsigned char)*cp))
43
Assuming the character is not a digit
44
Loop condition is false. Execution continues on line 1243
1241 mval = mval * 10 + hexdigit_to_int(*cp++);
1242
1243 if (*cp == '.') { /* centimeters */
45
Assuming the condition is false
46
Taking false branch
1244 cp++;
1245 if (isdigit((unsigned char)*cp)) {
1246 cmval = hexdigit_to_int(*cp++) * 10;
1247 if (isdigit((unsigned char)*cp)) {
1248 cmval += hexdigit_to_int(*cp++);
1249 }
1250 }
1251 }
1252
1253 if(mval >= poweroften[7]) {
47
Assuming the condition is true
48
Taking true branch
1254 assert(poweroften[7] != 0)((void)0);
1255 /* integer overflow possible for *100 */
1256 mantissa = mval / poweroften[7];
49
Division by zero
1257 exponent = 9; /* max */
1258 }
1259 else {
1260 cmval = (mval * 100) + cmval;
1261
1262 for (exponent = 0; exponent < 9; exponent++)
1263 if (cmval < poweroften[exponent+1])
1264 break;
1265
1266 assert(poweroften[exponent] != 0)((void)0);
1267 mantissa = cmval / poweroften[exponent];
1268 }
1269 if (mantissa > 9)
1270 mantissa = 9;
1271
1272 retval = (mantissa << 4) | exponent;
1273
1274 if (*cp == 'm') cp++;
1275
1276 *endptr = cp;
1277
1278 return (retval);
1279}
1280
1281/*
1282 * Parses a specific part of rdata.
1283 *
1284 * Returns:
1285 *
1286 * number of elements parsed
1287 * zero on error
1288 *
1289 */
1290uint16_t *
1291zparser_conv_loc(region_type *region, char *str)
1292{
1293 uint16_t *r;
1294 uint32_t *p;
1295 int i;
1296 int deg, min, secs; /* Secs is stored times 1000. */
1297 uint32_t lat = 0, lon = 0, alt = 0;
1298 /* encoded defaults: version=0 sz=1m hp=10000m vp=10m */
1299 uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13};
1300 char *start;
1301 double d;
1302
1303 for(;;) {
1
Loop condition is true. Entering loop body
14
Loop condition is true. Entering loop body
1304 deg = min = secs = 0;
1305
1306 /* Degrees */
1307 if (*str == '\0') {
2
Assuming the condition is false
3
Taking false branch
15
Assuming the condition is false
16
Taking false branch
1308 zc_error_prev_line("unexpected end of LOC data");
1309 return NULL((void *)0);
1310 }
1311
1312 if (!parse_int(str, &str, &deg, "degrees", 0, 180))
4
Taking false branch
17
Taking false branch
1313 return NULL((void *)0);
1314 if (!isspace((unsigned char)*str)) {
5
Assuming the character is a whitespace character
6
Taking false branch
18
Assuming the character is a whitespace character
19
Taking false branch
1315 zc_error_prev_line("space expected after degrees");
1316 return NULL((void *)0);
1317 }
1318 ++str;
1319
1320 /* Minutes? */
1321 if (isdigit((unsigned char)*str)) {
7
Assuming the character is not a digit
8
Taking false branch
20
Assuming the character is not a digit
21
Taking false branch
1322 if (!parse_int(str, &str, &min, "minutes", 0, 60))
1323 return NULL((void *)0);
1324 if (!isspace((unsigned char)*str)) {
1325 zc_error_prev_line("space expected after minutes");
1326 return NULL((void *)0);
1327 }
1328 ++str;
1329 }
1330
1331 /* Seconds? */
1332 if (isdigit((unsigned char)*str)) {
9
Taking false branch
22
Taking false branch
1333 start = str;
1334 if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
1335 return NULL((void *)0);
1336 }
1337
1338 if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) {
1339 return NULL((void *)0);
1340 }
1341
1342 if (!isspace((unsigned char)*str)) {
1343 zc_error_prev_line("space expected after seconds");
1344 return NULL((void *)0);
1345 }
1346 /* No need for precision specifiers, it's a double */
1347 if (sscanf(start, "%lf", &d) != 1) {
1348 zc_error_prev_line("error parsing seconds");
1349 }
1350
1351 if (d < 0.0 || d > 60.0) {
1352 zc_error_prev_line("seconds not in range 0.0 .. 60.0");
1353 }
1354
1355 secs = (int) (d * 1000.0 + 0.5);
1356 ++str;
1357 }
1358
1359 switch(*str) {
10
Control jumps to 'case 119:' at line 1373
23
Control jumps to 'case 110:' at line 1361
1360 case 'N':
1361 case 'n':
1362 lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
1363 break;
24
Execution continues on line 1380
1364 case 'E':
1365 case 'e':
1366 lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
1367 break;
1368 case 'S':
1369 case 's':
1370 lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
1371 break;
1372 case 'W':
1373 case 'w':
1374 lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
1375 break;
11
Execution continues on line 1380
1376 default:
1377 zc_error_prev_line("invalid latitude/longtitude: '%c'", *str);
1378 return NULL((void *)0);
1379 }
1380 ++str;
1381
1382 if (lat
11.1
'lat' is equal to 0
!= 0
&& lon != 0)
25
Assuming 'lat' is not equal to 0
26
Assuming 'lon' is not equal to 0
27
Taking true branch
1383 break;
1384
1385 if (!isspace((unsigned char)*str)) {
12
Assuming the character is a whitespace character
13
Taking false branch
1386 zc_error_prev_line("space expected after latitude/longitude");
1387 return NULL((void *)0);
1388 }
1389 ++str;
1390 }
1391
1392 /* Altitude */
1393 if (*str == '\0') {
28
Execution continues on line 1393
29
Assuming the condition is false
30
Taking false branch
1394 zc_error_prev_line("unexpected end of LOC data");
1395 return NULL((void *)0);
1396 }
1397
1398 if (!isspace((unsigned char)*str)) {
31
Assuming the character is a whitespace character
32
Taking false branch
1399 zc_error_prev_line("space expected before altitude");
1400 return NULL((void *)0);
1401 }
1402 ++str;
1403
1404 start = str;
1405
1406 /* Sign */
1407 if (*str == '+' || *str == '-') {
33
Assuming the condition is false
34
Assuming the condition is false
35
Taking false branch
1408 ++str;
1409 }
1410
1411 /* Meters of altitude... */
1412 if(strtol(str, &str, 10) == LONG_MAX0x7fffffffffffffffL) {
36
Assuming the condition is false
37
Taking false branch
1413 zc_error_prev_line("altitude too large, number overflow");
1414 return NULL((void *)0);
1415 }
1416 switch(*str) {
38
Control jumps to 'case 32:' at line 1417
1417 case ' ':
1418 case '\0':
1419 case 'm':
1420 break;
1421 case '.':
1422 if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) {
1423 return NULL((void *)0);
1424 }
1425 if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') {
1426 zc_error_prev_line("altitude fraction must be a number");
1427 return NULL((void *)0);
1428 }
1429 break;
1430 default:
1431 zc_error_prev_line("altitude must be expressed in meters");
1432 return NULL((void *)0);
1433 }
1434 if (!isspace((unsigned char)*str) && *str != '\0')
1435 ++str;
1436
1437 if (sscanf(start, "%lf", &d) != 1) {
39
Assuming the condition is false
40
Taking false branch
1438 zc_error_prev_line("error parsing altitude");
1439 }
1440
1441 alt = (uint32_t) (10000000.0 + d * 100 + 0.5);
1442
1443 if (!isspace((unsigned char)*str) && *str != '\0') {
1444 zc_error_prev_line("unexpected character after altitude");
1445 return NULL((void *)0);
1446 }
1447
1448 /* Now parse size, horizontal precision and vertical precision if any */
1449 for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) {
41
Loop condition is true. Entering loop body
1450 vszhpvp[i] = precsize_aton(str + 1, &str);
42
Calling 'precsize_aton'
1451
1452 if (!isspace((unsigned char)*str) && *str != '\0') {
1453 zc_error_prev_line("invalid size or precision");
1454 return NULL((void *)0);
1455 }
1456 }
1457
1458 /* Allocate required space... */
1459 r = alloc_rdata(region, 16);
1460 p = (uint32_t *) (r + 1);
1461
1462 memmove(p, vszhpvp, 4);
1463 write_uint32(p + 1, lat);
1464 write_uint32(p + 2, lon);
1465 write_uint32(p + 3, alt);
1466
1467 return r;
1468}
1469
1470/*
1471 * Convert an APL RR RDATA element.
1472 */
1473uint16_t *
1474zparser_conv_apl_rdata(region_type *region, char *str)
1475{
1476 int negated = 0;
1477 uint16_t address_family;
1478 uint8_t prefix;
1479 uint8_t maximum_prefix;
1480 uint8_t length;
1481 uint8_t address[IP6ADDRLEN(128/8)];
1482 char *colon = strchr(str, ':');
1483 char *slash = strchr(str, '/');
1484 int af;
1485 int rc;
1486 uint16_t rdlength;
1487 uint16_t *r;
1488 uint8_t *t;
1489 char *end;
1490 long p;
1491
1492 if (!colon) {
1493 zc_error("address family separator is missing");
1494 return NULL((void *)0);
1495 }
1496 if (!slash) {
1497 zc_error("prefix separator is missing");
1498 return NULL((void *)0);
1499 }
1500
1501 *colon = '\0';
1502 *slash = '\0';
1503
1504 if (*str == '!') {
1505 negated = 1;
1506 ++str;
1507 }
1508
1509 if (strcmp(str, "1") == 0) {
1510 address_family = htons(1)(__uint16_t)(__builtin_constant_p(1) ? (__uint16_t)(((__uint16_t
)(1) & 0xffU) << 8 | ((__uint16_t)(1) & 0xff00U
) >> 8) : __swap16md(1))
;
1511 af = AF_INET2;
1512 length = sizeof(in_addr_t);
1513 maximum_prefix = length * 8;
1514 } else if (strcmp(str, "2") == 0) {
1515 address_family = htons(2)(__uint16_t)(__builtin_constant_p(2) ? (__uint16_t)(((__uint16_t
)(2) & 0xffU) << 8 | ((__uint16_t)(2) & 0xff00U
) >> 8) : __swap16md(2))
;
1516 af = AF_INET624;
1517 length = IP6ADDRLEN(128/8);
1518 maximum_prefix = length * 8;
1519 } else {
1520 zc_error("invalid address family '%s'", str);
1521 return NULL((void *)0);
1522 }
1523
1524 rc = inet_pton(af, colon + 1, address);
1525 if (rc == 0) {
1526 zc_error("invalid address '%s'", colon + 1);
1527 return NULL((void *)0);
1528 } else if (rc == -1) {
1529 zc_error("inet_pton failed: %s", strerror(errno(*__errno())));
1530 return NULL((void *)0);
1531 }
1532
1533 /* Strip trailing zero octets. */
1534 while (length > 0 && address[length - 1] == 0)
1535 --length;
1536
1537
1538 p = strtol(slash + 1, &end, 10);
1539 if (p < 0 || p > maximum_prefix) {
1540 zc_error("prefix not in the range 0 .. %d", maximum_prefix);
1541 return NULL((void *)0);
1542 } else if (*end != '\0') {
1543 zc_error("invalid prefix '%s'", slash + 1);
1544 return NULL((void *)0);
1545 }
1546 prefix = (uint8_t) p;
1547
1548 rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length)
1549 + length);
1550 r = alloc_rdata(region, rdlength);
1551 t = (uint8_t *) (r + 1);
1552
1553 memcpy(t, &address_family, sizeof(address_family));
1554 t += sizeof(address_family);
1555 memcpy(t, &prefix, sizeof(prefix));
1556 t += sizeof(prefix);
1557 memcpy(t, &length, sizeof(length));
1558 if (negated) {
1559 *t |= APL_NEGATION_MASK0x80U;
1560 }
1561 t += sizeof(length);
1562 memcpy(t, address, length);
1563
1564 return r;
1565}
1566
1567/*
1568 * Below some function that also convert but not to wireformat
1569 * but to "normal" (int,long,char) types
1570 */
1571
1572uint32_t
1573zparser_ttl2int(const char *ttlstr, int* error)
1574{
1575 /* convert a ttl value to a integer
1576 * return the ttl in a int
1577 * -1 on error
1578 */
1579
1580 uint32_t ttl;
1581 const char *t;
1582
1583 ttl = strtottl(ttlstr, &t);
1584 if (*t != 0) {
1585 zc_error_prev_line("invalid TTL value: %s",ttlstr);
1586 *error = 1;
1587 }
1588
1589 return ttl;
1590}
1591
1592
1593void
1594zadd_rdata_wireformat(uint16_t *data)
1595{
1596 if (parser->current_rr.rdata_count >= MAXRDATALEN64) {
1597 zc_error_prev_line("too many rdata elements");
1598 } else {
1599 parser->current_rr.rdatas[parser->current_rr.rdata_count].data
1600 = data;
1601 ++parser->current_rr.rdata_count;
1602 }
1603}
1604
1605/**
1606 * Used for TXT RR's to grow with undefined number of strings.
1607 */
1608void
1609zadd_rdata_txt_wireformat(uint16_t *data, int first)
1610{
1611 rdata_atom_type *rd;
1612 if (parser->current_rr.rdata_count >= MAXRDATALEN64) {
1613 zc_error_prev_line("too many rdata txt elements");
1614 return;
1615 }
1616
1617 /* First STR in str_seq, allocate 65K in first unused rdata
1618 * else find last used rdata */
1619 if (first) {
1620 rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count];
1621 if ((rd->data = (uint16_t *) region_alloc(parser->rr_region,
1622 sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL((void *)0)) {
1623 zc_error_prev_line("Could not allocate memory for TXT RR");
1624 return;
1625 }
1626 parser->current_rr.rdata_count++;
1627 rd->data[0] = 0;
1628 }
1629 else
1630 rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1631
1632 if ((size_t)rd->data[0] + (size_t)data[0] > 65535) {
1633 zc_error_prev_line("too large rdata element");
1634 return;
1635 }
1636
1637 memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]);
1638 rd->data[0] += data[0];
1639}
1640
1641/**
1642 * Clean up after last call of zadd_rdata_txt_wireformat
1643 */
1644void
1645zadd_rdata_txt_clean_wireformat()
1646{
1647 uint16_t *tmp_data;
1648 rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1649 if(!rd || !rd->data)
1650 return; /* previous syntax failure */
1651 if ((tmp_data = (uint16_t *) region_alloc(parser->region,
1652 ((size_t)rd->data[0]) + ((size_t)2))) != NULL((void *)0)) {
1653 memcpy(tmp_data, rd->data, rd->data[0] + 2);
1654 /* rd->data of u16+65535 freed when rr_region is freed */
1655 rd->data = tmp_data;
1656 }
1657 else {
1658 /* We could not get memory in non-volatile region */
1659 zc_error_prev_line("could not allocate memory for rdata");
1660 return;
1661 }
1662}
1663
1664static int
1665svcparam_key_cmp(const void *a, const void *b)
1666{
1667 return ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)a)))
1668 - ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)b)));
1669}
1670
1671void
1672zadd_rdata_svcb_check_wireformat()
1673{
1674 size_t i;
1675 uint8_t paramkeys[65536];
1676 int prev_key = - 1;
1677 int key = 0;
1678 size_t size;
1679 uint16_t *mandatory_values;
1680
1681 if (parser->current_rr.rdata_count <= 2) {
1682 if (!parser->error_occurred)
1683 zc_error_prev_line("invalid SVCB or HTTPS rdata");
1684 return;
1685 } else for (i = 2; i < parser->current_rr.rdata_count; i++) {
1686 if (parser->current_rr.rdatas[i].data == NULL((void *)0)
1687 || rdata_atom_data(parser->current_rr.rdatas[i]) == NULL((void *)0)
1688 || rdata_atom_size(parser->current_rr.rdatas[i]) < 4) {
1689 if (!parser->error_occurred)
1690 zc_error_prev_line("invalid SVCB or HTTPS rdata");
1691 return;
1692 }
1693 }
1694 /* After this point, all rdatas do have data larger than 4 bytes.
1695 * So we may assume a uint16_t SVCB key followed by uint16_t length
1696 * in each rdata in the remainder of this function.
1697 */
1698 memset(paramkeys, 0, sizeof(paramkeys));
1699 /*
1700 * In draft-ietf-dnsop-svcb-https-04 Section 7:
1701 * In wire format, the keys are represented by their numeric values in
1702 * network byte order, concatenated in ascending order.
1703 *
1704 * svcparam_key_cmp assumes the rdatas to have a SVCB key, which is
1705 * safe because we checked.
1706 *
1707 */
1708 qsort( (void *)&parser->current_rr.rdatas[2]
1709 , parser->current_rr.rdata_count - 2
1710 , sizeof(rdata_atom_type)
1711 , svcparam_key_cmp
1712 );
1713
1714 for (i = 2; i < parser->current_rr.rdata_count; i++) {
1715 assert(parser->current_rr.rdatas[i].data)((void)0);
1716 assert(rdata_atom_data(parser->current_rr.rdatas[i]))((void)0);
1717 assert(rdata_atom_size(parser->current_rr.rdatas[i]) >= sizeof(uint16_t))((void)0);
1718
1719 key = read_uint16(rdata_atom_data(parser->current_rr.rdatas[i]));
1720
1721 /* In draft-ietf-dnsop-svcb-https-04 Section 7:
1722 *
1723 * Keys (...) MUST NOT appear more than once.
1724 *
1725 * If they key has already been seen, we have a duplicate
1726 */
1727 if (!paramkeys[key])
1728 /* keep track of keys that are present */
1729 paramkeys[key] = 1;
1730
1731 else if (key < SVCPARAMKEY_COUNT8) {
1732 if(zone_is_slave(parser->current_zone->opts))
1733 zc_warning_prev_line(
1734 "Duplicate key found: %s",
1735 svcparamkey_strs[key]);
1736 else {
1737 zc_error_prev_line(
1738 "Duplicate key found: %s",
1739 svcparamkey_strs[key]);
1740 }
1741 } else if(zone_is_slave(parser->current_zone->opts))
1742 zc_warning_prev_line(
1743 "Duplicate key found: key%d", key);
1744 else
1745 zc_error_prev_line(
1746 "Duplicate key found: key%d", key);
1747 }
1748 /* Checks when a mandatory key is present */
1749 if (!paramkeys[SVCB_KEY_MANDATORY0])
1750 return;
1751
1752 size = rdata_atom_size(parser->current_rr.rdatas[2]);
1753 assert(size >= 4)((void)0);
1754 mandatory_values = (void*)rdata_atom_data(parser->current_rr.rdatas[2]);
1755 mandatory_values += 2; /* skip the key type and length */
1756
1757 if (size % 2)
1758 zc_error_prev_line("mandatory rdata must be a multiple of shorts");
1759
1760 else for (i = 0; i < (size - 4)/2; i++) {
1761 key = ntohs(mandatory_values[i])(__uint16_t)(__builtin_constant_p(mandatory_values[i]) ? (__uint16_t
)(((__uint16_t)(mandatory_values[i]) & 0xffU) << 8 |
((__uint16_t)(mandatory_values[i]) & 0xff00U) >> 8
) : __swap16md(mandatory_values[i]))
;
1762
1763 if (paramkeys[key])
1764 ; /* pass */
1765
1766 else if (key < SVCPARAMKEY_COUNT8) {
1767 if(zone_is_slave(parser->current_zone->opts))
1768 zc_warning_prev_line("mandatory SvcParamKey: %s is missing "
1769 "the record", svcparamkey_strs[key]);
1770 else
1771 zc_error_prev_line("mandatory SvcParamKey: %s is missing "
1772 "the record", svcparamkey_strs[key]);
1773 } else {
1774 if(zone_is_slave(parser->current_zone->opts))
1775 zc_warning_prev_line("mandatory SvcParamKey: key%d is missing "
1776 "the record", key);
1777 else
1778 zc_error_prev_line("mandatory SvcParamKey: key%d is missing "
1779 "the record", key);
1780 }
1781
1782 /* In draft-ietf-dnsop-svcb-https-04 Section 8
1783 * automatically mandatory MUST NOT appear in its own value-list
1784 */
1785 if (key == SVCB_KEY_MANDATORY0) {
1786 if(zone_is_slave(parser->current_zone->opts))
1787 zc_warning_prev_line("mandatory MUST not be included"
1788 " as mandatory parameter");
1789 else
1790 zc_error_prev_line("mandatory MUST not be included"
1791 " as mandatory parameter");
1792 }
1793 if (key == prev_key) {
1794 if(zone_is_slave(parser->current_zone->opts))
1795 zc_warning_prev_line("Keys inSvcParam mandatory "
1796 "MUST NOT appear more than once.");
1797 else
1798 zc_error_prev_line("Keys in SvcParam mandatory "
1799 "MUST NOT appear more than once.");
1800 }
1801 prev_key = key;
1802 }
1803}
1804
1805void
1806zadd_rdata_domain(domain_type *domain)
1807{
1808 if (parser->current_rr.rdata_count >= MAXRDATALEN64) {
1809 zc_error_prev_line("too many rdata elements");
1810 } else {
1811 parser->current_rr.rdatas[parser->current_rr.rdata_count].domain
1812 = domain;
1813 domain->usage ++; /* new reference to domain */
1814 ++parser->current_rr.rdata_count;
1815 }
1816}
1817
1818void
1819parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
1820{
1821 buffer_type packet;
1822 uint16_t size;
1823 ssize_t rdata_count;
1824 ssize_t i;
1825 rdata_atom_type *rdatas;
1826
1827 if (wireformat) {
1828 size = *wireformat;
1829 } else {
1830 return;
1831 }
1832
1833 buffer_create_from(&packet, wireformat + 1, *wireformat);
1834 rdata_count = rdata_wireformat_to_rdata_atoms(parser->region,
1835 parser->db->domains,
1836 type,
1837 size,
1838 &packet,
1839 &rdatas);
1840 if (rdata_count == -1) {
1841 zc_error_prev_line("bad unknown RDATA");
1842 return;
1843 }
1844
1845 for (i = 0; i < rdata_count; ++i) {
1846 if (rdata_atom_is_domain(type, i)) {
1847 zadd_rdata_domain(rdatas[i].domain);
1848 } else {
1849 zadd_rdata_wireformat(rdatas[i].data);
1850 }
1851 }
1852 region_recycle(parser->region, rdatas,
1853 rdata_count*sizeof(rdata_atom_type));
1854}
1855
1856
1857/*
1858 * Compares two rdata arrays.
1859 *
1860 * Returns:
1861 *
1862 * zero if they are equal
1863 * non-zero if not
1864 *
1865 */
1866static int
1867zrdatacmp(uint16_t type, rr_type *a, rr_type *b)
1868{
1869 int i = 0;
1870
1871 assert(a)((void)0);
1872 assert(b)((void)0);
1873
1874 /* One is shorter than another */
1875 if (a->rdata_count != b->rdata_count)
1876 return 1;
1877
1878 /* Compare element by element */
1879 for (i = 0; i < a->rdata_count; ++i) {
1880 if (rdata_atom_is_domain(type, i)) {
1881 if (rdata_atom_domain(a->rdatas[i])
1882 != rdata_atom_domain(b->rdatas[i]))
1883 {
1884 return 1;
1885 }
1886 } else if(rdata_atom_is_literal_domain(type, i)) {
1887 if (rdata_atom_size(a->rdatas[i])
1888 != rdata_atom_size(b->rdatas[i]))
1889 return 1;
1890 if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]),
1891 rdata_atom_data(b->rdatas[i]),
1892 rdata_atom_size(a->rdatas[i])))
1893 return 1;
1894 } else {
1895 if (rdata_atom_size(a->rdatas[i])
1896 != rdata_atom_size(b->rdatas[i]))
1897 {
1898 return 1;
1899 }
1900 if (memcmp(rdata_atom_data(a->rdatas[i]),
1901 rdata_atom_data(b->rdatas[i]),
1902 rdata_atom_size(a->rdatas[i])) != 0)
1903 {
1904 return 1;
1905 }
1906 }
1907 }
1908
1909 /* Otherwise they are equal */
1910 return 0;
1911}
1912
1913/*
1914 *
1915 * Opens a zone file.
1916 *
1917 * Returns:
1918 *
1919 * - pointer to the parser structure
1920 * - NULL on error and errno set
1921 *
1922 */
1923static int
1924zone_open(const char *filename, uint32_t ttl, uint16_t klass,
1925 const dname_type *origin)
1926{
1927 /* Open the zone file... */
1928 if (strcmp(filename, "-") == 0) {
1929 yyin = stdin(&__sF[0]);
1930 filename = "<stdin>";
1931 warn_if_directory("zonefile from stdin", yyin, filename);
1932 } else {
1933 if (!(yyin = fopen(filename, "r"))) {
1934 return 0;
1935 }
1936 warn_if_directory("zonefile", yyin, filename);
1937 }
1938
1939 zparser_init(filename, ttl, klass, origin);
1940
1941 return 1;
1942}
1943
1944
1945void
1946set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT256][NSEC_WINDOW_BITS_SIZE(256 / 8)],
1947 uint16_t index)
1948{
1949 /*
1950 * The bits are counted from left to right, so bit #0 is the
1951 * left most bit.
1952 */
1953 uint8_t window = index / 256;
1954 uint8_t bit = index % 256;
1955
1956 bits[window][bit / 8] |= (1 << (7 - bit % 8));
1957}
1958
1959
1960static int
1961has_soa(domain_type* domain)
1962{
1963 rrset_type* p = NULL((void *)0);
1964 if(!domain) return 0;
1965 for(p = domain->rrsets; p; p = p->next)
1966 if(rrset_rrtype(p) == TYPE_SOA6)
1967 return 1;
1968 return 0;
1969}
1970
1971int
1972process_rr(void)
1973{
1974 zone_type *zone = parser->current_zone;
1975 rr_type *rr = &parser->current_rr;
1976 rrset_type *rrset;
1977 size_t max_rdlength;
1978 int i;
1979 rrtype_descriptor_type *descriptor
1980 = rrtype_descriptor_by_type(rr->type);
1981
1982 /* We only support IN class */
1983 if (rr->klass != CLASS_IN1) {
1984 if(zone_is_slave(zone->opts))
1985 zc_warning_prev_line("only class IN is supported");
1986 else
1987 zc_error_prev_line("only class IN is supported");
1988 return 0;
1989 }
1990
1991 /* Make sure the maximum RDLENGTH does not exceed 65535 bytes. */
1992 max_rdlength = rdata_maximum_wireformat_size(
1993 descriptor, rr->rdata_count, rr->rdatas);
1994
1995 if (max_rdlength > MAX_RDLENGTH65535) {
1996 zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH65535);
1997 return 0;
1998 }
1999
2000 /* We cannot print invalid owner names,
2001 * so error on that before it is used in printing other errors.
2002 */
2003 if (rr->owner == error_domain
2004 || domain_dname(rr->owner) == error_dname) {
2005 zc_error_prev_line("invalid owner name");
2006 return 0;
2007 }
2008
2009 /* we have the zone already */
2010 assert(zone)((void)0);
2011 if (rr->type == TYPE_SOA6) {
2012 if (rr->owner != zone->apex) {
2013 char s[MAXDOMAINLEN255*5];
2014 snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
2015 zc_error_prev_line(
2016 "SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s);
2017 return 0;
2018 }
2019 if(has_soa(rr->owner)) {
2020 if(zone_is_slave(zone->opts))
2021 zc_warning_prev_line("this SOA record was already encountered");
2022 else
2023 zc_error_prev_line("this SOA record was already encountered");
2024 return 0;
2025 }
2026 rr->owner->is_apex = 1;
2027 }
2028
2029 if (!domain_is_subdomain(rr->owner, zone->apex))
2030 {
2031 char s[MAXDOMAINLEN255*5];
2032 snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
2033 if(zone_is_slave(zone->opts))
2034 zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
2035 else
2036 zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
2037 return 0;
2038 }
2039
2040 /* Do we have this type of rrset already? */
2041 rrset = domain_find_rrset(rr->owner, zone, rr->type);
2042 if (!rrset) {
2043 rrset = (rrset_type *) region_alloc(parser->region,
2044 sizeof(rrset_type));
2045 rrset->zone = zone;
2046 rrset->rr_count = 1;
2047 rrset->rrs = (rr_type *) region_alloc(parser->region,
2048 sizeof(rr_type));
2049 rrset->rrs[0] = *rr;
2050
2051 /* Add it */
2052 domain_add_rrset(rr->owner, rrset);
2053 } else {
2054 rr_type* o;
2055 if (rr->type != TYPE_RRSIG46 && rrset->rrs[0].ttl != rr->ttl) {
2056 zc_warning_prev_line(
2057 "%s TTL %u does not match the TTL %u of the %s RRset",
2058 domain_to_string(rr->owner), (unsigned)rr->ttl,
2059 (unsigned)rrset->rrs[0].ttl,
2060 rrtype_to_string(rr->type));
2061 }
2062
2063 /* Search for possible duplicates... */
2064 for (i = 0; i < rrset->rr_count; i++) {
2065 if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) {
2066 break;
2067 }
2068 }
2069
2070 /* Discard the duplicates... */
2071 if (i < rrset->rr_count) {
2072 /* add rdatas to recycle bin. */
2073 size_t i;
2074 for (i = 0; i < rr->rdata_count; i++) {
2075 if(!rdata_atom_is_domain(rr->type, i))
2076 region_recycle(parser->region, rr->rdatas[i].data,
2077 rdata_atom_size(rr->rdatas[i])
2078 + sizeof(uint16_t));
2079 }
2080 region_recycle(parser->region, rr->rdatas,
2081 sizeof(rdata_atom_type)*rr->rdata_count);
2082 return 0;
2083 }
2084 if(rrset->rr_count == 65535) {
2085 zc_error_prev_line("too many RRs for domain RRset");
2086 return 0;
2087 }
2088
2089 /* Add it... */
2090 o = rrset->rrs;
2091 rrset->rrs = (rr_type *) region_alloc_array(parser->region,
2092 (rrset->rr_count + 1), sizeof(rr_type));
2093 memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type));
2094 region_recycle(parser->region, o,
2095 (rrset->rr_count) * sizeof(rr_type));
2096 rrset->rrs[rrset->rr_count] = *rr;
2097 ++rrset->rr_count;
2098 }
2099
2100 if(rr->type == TYPE_DNAME39 && rrset->rr_count > 1) {
2101 if(zone_is_slave(zone->opts))
2102 zc_warning_prev_line("multiple DNAMEs at the same name");
2103 else
2104 zc_error_prev_line("multiple DNAMEs at the same name");
2105 }
2106 if(rr->type == TYPE_CNAME5 && rrset->rr_count > 1) {
2107 if(zone_is_slave(zone->opts))
2108 zc_warning_prev_line("multiple CNAMEs at the same name");
2109 else
2110 zc_error_prev_line("multiple CNAMEs at the same name");
2111 }
2112 if((rr->type == TYPE_DNAME39 && domain_find_rrset(rr->owner, zone, TYPE_CNAME5))
2113 ||(rr->type == TYPE_CNAME5 && domain_find_rrset(rr->owner, zone, TYPE_DNAME39))) {
2114 if(zone_is_slave(zone->opts))
2115 zc_warning_prev_line("DNAME and CNAME at the same name");
2116 else
2117 zc_error_prev_line("DNAME and CNAME at the same name");
2118 }
2119 if(domain_find_rrset(rr->owner, zone, TYPE_CNAME5) &&
2120 domain_find_non_cname_rrset(rr->owner, zone)) {
2121 if(zone_is_slave(zone->opts))
2122 zc_warning_prev_line("CNAME and other data at the same name");
2123 else
2124 zc_error_prev_line("CNAME and other data at the same name");
2125 }
2126
2127 /* Check we have SOA */
2128 if(rr->owner == zone->apex)
2129 apex_rrset_checks(parser->db, rrset, rr->owner);
2130
2131 if(parser->line % ZONEC_PCT_COUNT100000 == 0 && time(NULL((void *)0)) > startzonec + ZONEC_PCT_TIME5) {
2132 struct stat buf;
2133 startzonec = time(NULL((void *)0));
2134 buf.st_size = 0;
2135 fstat(fileno(yyin)(!__isthreaded ? ((yyin)->_file) : (fileno)(yyin)), &buf);
2136 if(buf.st_size == 0) buf.st_size = 1;
2137 VERBOSITY(1, (LOG_INFO, "parse %s %d %%",do { if ((1) <= verbosity) { log_msg (6, "parse %s %d %%",
parser->current_zone->opts->name, (int)((uint64_t)ftell
(yyin)*(uint64_t)100/(uint64_t)buf.st_size)) ; } } while (0)
2138 parser->current_zone->opts->name,do { if ((1) <= verbosity) { log_msg (6, "parse %s %d %%",
parser->current_zone->opts->name, (int)((uint64_t)ftell
(yyin)*(uint64_t)100/(uint64_t)buf.st_size)) ; } } while (0)
2139 (int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size)))do { if ((1) <= verbosity) { log_msg (6, "parse %s %d %%",
parser->current_zone->opts->name, (int)((uint64_t)ftell
(yyin)*(uint64_t)100/(uint64_t)buf.st_size)) ; } } while (0)
;
2140 }
2141 ++totalrrs;
2142 return 1;
2143}
2144
2145/*
2146 * Find rrset type for any zone
2147 */
2148static rrset_type*
2149domain_find_rrset_any(domain_type *domain, uint16_t type)
2150{
2151 rrset_type *result = domain->rrsets;
2152 while (result) {
2153 if (rrset_rrtype(result) == type) {
2154 return result;
2155 }
2156 result = result->next;
2157 }
2158 return NULL((void *)0);
2159}
2160
2161/*
2162 * Check for DNAME type. Nothing is allowed below it
2163 */
2164static void
2165check_dname(zone_type* zone)
2166{
2167 domain_type* domain;
2168 for(domain = zone->apex; domain && domain_is_subdomain(domain,
2169 zone->apex); domain=domain_next(domain))
2170 {
2171 if(domain->is_existing) {
2172 /* there may not be DNAMEs above it */
2173 domain_type* parent = domain->parent;
2174#ifdef NSEC3
2175 if(domain_has_only_NSEC3(domain, NULL((void *)0)))
2176 continue;
2177#endif
2178 while(parent) {
2179 if(domain_find_rrset_any(parent, TYPE_DNAME39)) {
2180 zc_error("While checking node %s,",
2181 domain_to_string(domain));
2182 zc_error("DNAME at %s has data below it. "
2183 "This is not allowed (rfc 2672).",
2184 domain_to_string(parent));
2185 return;
2186 }
2187 parent = parent->parent;
2188 }
2189 }
2190 }
2191}
2192
2193/*
2194 * Reads the specified zone into the memory
2195 * nsd_options can be NULL if no config file is passed.
2196 */
2197unsigned int
2198zonec_read(const char* name, const char* zonefile, zone_type* zone)
2199{
2200 const dname_type *dname;
2201
2202 totalrrs = 0;
2203 startzonec = time(NULL((void *)0));
2204 parser->errors = 0;
2205
2206 dname = dname_parse(parser->rr_region, name);
2207 if (!dname) {
2208 zc_error("incorrect zone name '%s'", name);
2209 return 1;
2210 }
2211
2212 /* Open the zone file */
2213 if (!zone_open(zonefile, 3600, CLASS_IN1, dname)) {
2214 zc_error("cannot open '%s': %s", zonefile, strerror(errno(*__errno())));
2215 return 1;
2216 }
2217 parser->current_zone = zone;
2218
2219 /* Parse and process all RRs. */
2220 yyparse();
2221
2222 /* remove origin if it was unused */
2223 if(parser->origin != error_domain)
2224 domain_table_deldomain(parser->db, parser->origin);
2225 /* rr_region has been emptied by now */
2226 dname = dname_parse(parser->rr_region, name);
2227
2228 /* check if zone file contained a correct SOA record */
2229 if (!parser->current_zone) {
2230 zc_error("zone configured as '%s' has no content.", name);
2231 } else if(!parser->current_zone->soa_rrset ||
2232 parser->current_zone->soa_rrset->rr_count == 0) {
2233 zc_error("zone configured as '%s' has no SOA record.", name);
2234 } else if(dname_compare(domain_dname(
2235 parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
2236 zc_error("zone configured as '%s', but SOA has owner '%s'.",
2237 name, domain_to_string(
2238 parser->current_zone->soa_rrset->rrs[0].owner));
2239 }
2240 region_free_all(parser->rr_region);
2241
2242 parser_flush();
2243 fclose(yyin);
2244 if(!zone_is_slave(zone->opts))
2245 check_dname(zone);
2246
2247 parser->filename = NULL((void *)0);
2248 return parser->errors;
2249}
2250
2251
2252/*
2253 * setup parse
2254 */
2255void
2256zonec_setup_parser(namedb_type* db)
2257{
2258 region_type* rr_region = region_create(xalloc, free);
2259 parser = zparser_create(db->region, rr_region, db);
2260 assert(parser)((void)0);
2261 /* Unique pointers used to mark errors. */
2262 error_dname = (dname_type *) region_alloc(db->region, 1);
2263 error_domain = (domain_type *) region_alloc(db->region, 1);
2264 /* Open the network database */
2265 setprotoent(1);
2266 setservent(1);
2267}
2268
2269/** desetup parse */
2270void
2271zonec_desetup_parser(void)
2272{
2273 if(parser) {
2274 endservent();
2275 endprotoent();
2276 region_destroy(parser->rr_region);
2277 /* removed when parser->region(=db->region) is destroyed:
2278 * region_recycle(parser->region, (void*)error_dname, 1);
2279 * region_recycle(parser->region, (void*)error_domain, 1); */
2280 /* clear memory for exit, but this is not portable to
2281 * other versions of lex. yylex_destroy(); */
2282#ifdef MEMCLEAN /* OS collects memory pages */
2283 yylex_destroy();
2284#endif
2285 }
2286}
2287
2288static domain_table_type* orig_domains = NULL((void *)0);
2289static region_type* orig_region = NULL((void *)0);
2290static region_type* orig_dbregion = NULL((void *)0);
2291
2292/** setup for string parse */
2293void
2294zonec_setup_string_parser(region_type* region, domain_table_type* domains)
2295{
2296 assert(parser)((void)0); /* global parser must be setup */
2297 orig_domains = parser->db->domains;
2298 orig_region = parser->region;
2299 orig_dbregion = parser->db->region;
2300 parser->region = region;
2301 parser->db->region = region;
2302 parser->db->domains = domains;
2303 zparser_init("string", 3600, CLASS_IN1, domain_dname(domains->root));
2304}
2305
2306/** desetup string parse */
2307void
2308zonec_desetup_string_parser(void)
2309{
2310 parser->region = orig_region;
2311 parser->db->domains = orig_domains;
2312 parser->db->region = orig_dbregion;
2313}
2314
2315/** parse a string into temporary storage */
2316int
2317zonec_parse_string(region_type* region, domain_table_type* domains,
2318 zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
2319{
2320 int errors;
2321 zonec_setup_string_parser(region, domains);
2322 parser->current_zone = zone;
2323 parser->errors = 0;
2324 totalrrs = 0;
2325 startzonec = time(NULL((void *)0))+100000; /* disable */
2326 parser_push_stringbuf(str);
2327 yyparse();
2328 parser_pop_stringbuf();
2329 errors = parser->errors;
2330 *num_rrs = totalrrs;
2331 if(*num_rrs == 0)
2332 *parsed = NULL((void *)0);
2333 else *parsed = parser->prev_dname;
2334 /* remove origin if it was not used during the parse */
2335 if(parser->origin != error_domain)
2336 domain_table_deldomain(parser->db, parser->origin);
2337 region_free_all(parser->rr_region);
2338 zonec_desetup_string_parser();
2339 parser_flush();
2340 return errors;
2341}
2342
2343/** check SSHFP type for failures and emit warnings */
2344void check_sshfp(void)
2345{
2346 uint8_t hash;
2347 uint16_t size;
2348 if(parser->current_rr.rdata_count < 3)
2349 return; /* cannot check it, too few rdata elements */
2350 if(!parser->current_rr.rdatas[0].data ||
2351 !parser->current_rr.rdatas[1].data ||
2352 !parser->current_rr.rdatas[2].data ||
2353 !parser->current_rr.owner)
2354 return; /* cannot check, NULLs (due to earlier errors) */
2355 if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1)
2356 return; /* wrong size of the hash type rdata element */
2357 hash = rdata_atom_data(parser->current_rr.rdatas[1])[0];
2358 size = rdata_atom_size(parser->current_rr.rdatas[2]);
2359 if(hash == 1 && size != 20) {
2360 zc_warning_prev_line("SSHFP %s of type SHA1 has hash of "
2361 "wrong length, %d bytes, should be 20",
2362 domain_to_string(parser->current_rr.owner),
2363 (int)size);
2364 } else if(hash == 2 && size != 32) {
2365 zc_warning_prev_line("SSHFP %s of type SHA256 has hash of "
2366 "wrong length, %d bytes, should be 32",
2367 domain_to_string(parser->current_rr.owner),
2368 (int)size);
2369 }
2370}
2371
2372void
2373apex_rrset_checks(namedb_type* db, rrset_type* rrset, domain_type* domain)
2374{
2375 uint32_t soa_minimum;
2376 unsigned i;
2377 zone_type* zone = rrset->zone;
2378 assert(domain == zone->apex)((void)0);
2379 (void)domain;
2380 if (rrset_rrtype(rrset) == TYPE_SOA6) {
2381 zone->soa_rrset = rrset;
2382
2383 /* BUG #103 add another soa with a tweaked ttl */
2384 if(zone->soa_nx_rrset == 0) {
2385 zone->soa_nx_rrset = region_alloc(db->region,
2386 sizeof(rrset_type));
2387 zone->soa_nx_rrset->rr_count = 1;
2388 zone->soa_nx_rrset->next = 0;
2389 zone->soa_nx_rrset->zone = zone;
2390 zone->soa_nx_rrset->rrs = region_alloc(db->region,
2391 sizeof(rr_type));
2392 }
2393 memcpy(zone->soa_nx_rrset->rrs, rrset->rrs, sizeof(rr_type));
2394
2395 /* check the ttl and MINIMUM value and set accordingly */
2396 memcpy(&soa_minimum, rdata_atom_data(rrset->rrs->rdatas[6]),
2397 rdata_atom_size(rrset->rrs->rdatas[6]));
2398 if (rrset->rrs->ttl > ntohl(soa_minimum)(__uint32_t)(__builtin_constant_p(soa_minimum) ? (__uint32_t)
(((__uint32_t)(soa_minimum) & 0xff) << 24 | ((__uint32_t
)(soa_minimum) & 0xff00) << 8 | ((__uint32_t)(soa_minimum
) & 0xff0000) >> 8 | ((__uint32_t)(soa_minimum) &
0xff000000) >> 24) : __swap32md(soa_minimum))
) {
2399 zone->soa_nx_rrset->rrs[0].ttl = ntohl(soa_minimum)(__uint32_t)(__builtin_constant_p(soa_minimum) ? (__uint32_t)
(((__uint32_t)(soa_minimum) & 0xff) << 24 | ((__uint32_t
)(soa_minimum) & 0xff00) << 8 | ((__uint32_t)(soa_minimum
) & 0xff0000) >> 8 | ((__uint32_t)(soa_minimum) &
0xff000000) >> 24) : __swap32md(soa_minimum))
;
2400 }
2401 } else if (rrset_rrtype(rrset) == TYPE_NS2) {
2402 zone->ns_rrset = rrset;
2403 } else if (rrset_rrtype(rrset) == TYPE_RRSIG46) {
2404 for (i = 0; i < rrset->rr_count; ++i) {
2405 if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY48){
2406 zone->is_secure = 1;
2407 break;
2408 }
2409 }
2410 }
2411}