xref: /openbsd/regress/lib/libc/asr/bin/common.c (revision e5dd7070)
1 /*	$OpenBSD: common.c,v 1.4 2018/12/15 15:16:12 eric Exp $	*/
2 /*
3  * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
4  *
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.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
21 #include <arpa/nameser.h>
22 
23 #include <err.h>
24 #include <errno.h>
25 #include <inttypes.h>
26 #include <netdb.h>
27 #include <resolv.h>
28 #include <stdio.h>
29 #include <string.h>
30 
31 #include "common.h"
32 
33 int long_err;
34 int gai_errno;
35 int rrset_errno;
36 
37 
38 char *
39 gethostarg(char *n)
40 {
41 	if (n == NULL)
42 		return (n);
43 	if (!strcmp(n, "NULL"))
44 		return (NULL);
45 	if (!strcmp(n, "EMPTY"))
46 		return ("");
47 	return (n);
48 }
49 
50 const char *rrsetstrerror(int);
51 char * print_addr(const struct sockaddr *, char *, size_t);
52 
53 struct kv { int code; const char *name; };
54 
55 struct kv kv_family[] = {
56 	{ AF_UNIX,	"unix" },
57 	{ AF_INET,	"inet" },
58 	{ AF_INET6,	"inet6" },
59 	{ 0,	NULL, }
60 };
61 struct kv kv_socktype[] = {
62 	{ SOCK_STREAM,		"stream" },
63 	{ SOCK_DGRAM,		"dgram" },
64 	{ SOCK_RAW,		"raw" },
65 	{ SOCK_SEQPACKET,	"seqpacket" },
66 	{ 0,	NULL, }
67 };
68 struct kv kv_protocol[] = {
69 	{ IPPROTO_UDP, "udp" },
70 	{ IPPROTO_TCP, "tcp" },
71 	{ IPPROTO_ICMP, "icmp" },
72 	{ IPPROTO_ICMPV6, "icmpv6" },
73 	{ 0,	NULL, }
74 };
75 
76 static const char *
77 kv_lookup_name(struct kv *kv, int code, char *buf, size_t sz)
78 {
79 	while (kv->name) {
80 		if (kv->code == code)
81 			return (kv->name);
82 		kv++;
83 	}
84 	snprintf(buf, sz, "%i", code);
85 	return (buf);
86 }
87 
88 struct keyval {
89         const char *key;
90         int	    value;
91 };
92 
93 static struct keyval kv_class[] = {
94 	{ "IN",	C_IN },
95 	{ "CHAOS", C_CHAOS },
96 	{ "HS", C_HS },
97 	{ "ANY", C_ANY },
98 	{ NULL, 	0 },
99 };
100 
101 static struct keyval kv_type[] = {
102 	{ "A",		T_A	},
103 	{ "NS",		T_NS	},
104 	{ "MD",		T_MD	},
105 	{ "MF",		T_MF	},
106 	{ "CNAME",	T_CNAME	},
107 	{ "SOA",	T_SOA	},
108 	{ "MB",		T_MB	},
109 	{ "MG",		T_MG	},
110 	{ "MR",		T_MR	},
111 	{ "NULL",	T_NULL	},
112 	{ "WKS",	T_WKS	},
113 	{ "PTR",	T_PTR	},
114 	{ "HINFO",	T_HINFO	},
115 	{ "MINFO",	T_MINFO	},
116 	{ "MX",		T_MX	},
117 	{ "TXT",	T_TXT	},
118 
119 	{ "AAAA",	T_AAAA	},
120 
121 	{ "AXFR",	T_AXFR	},
122 	{ "MAILB",	T_MAILB	},
123 	{ "MAILA",	T_MAILA	},
124 	{ "ANY",	T_ANY	},
125 	{ NULL, 	0 },
126 };
127 
128 static struct keyval kv_rcode[] = {
129 	{ "NOERROR",	NOERROR	},
130 	{ "FORMERR",	FORMERR },
131 	{ "SERVFAIL",	SERVFAIL },
132 	{ "NXDOMAIN",	NXDOMAIN },
133 	{ "NOTIMP",	NOTIMP },
134 	{ "REFUSED",	REFUSED },
135 	{ NULL, 	0 },
136 };
137 
138 static struct keyval kv_resopt[] = {
139 	{ "DEBUG",	RES_DEBUG },
140 	{ "AAONLY",	RES_AAONLY },
141 	{ "USEVC",	RES_USEVC },
142 	{ "PRIMARY",	RES_PRIMARY },
143 	{ "IGNTC",	RES_IGNTC },
144 	{ "RECURSE",	RES_RECURSE },
145 	{ "DEFNAMES",	RES_DEFNAMES },
146 	{ "STAYOPEN",	RES_STAYOPEN },
147 	{ "DNSRCH",	RES_DNSRCH },
148 	{ "INSECURE1",	RES_INSECURE1 },
149 	{ "INSECURE2",	RES_INSECURE2 },
150 	{ "NOALIASES",	RES_NOALIASES },
151 	{ "USE_INET6",	RES_USE_INET6 },
152 	{ "USE_EDNS0",	RES_USE_EDNS0 },
153 	{ "USE_DNSSEC",	RES_USE_DNSSEC },
154 	{ NULL, 	0 },
155 };
156 
157 const char *
158 rcodetostr(uint16_t v)
159 {
160 	static char	buf[16];
161 	size_t		i;
162 
163 	for(i = 0; kv_rcode[i].key; i++)
164 		if (kv_rcode[i].value == v)
165 			return (kv_rcode[i].key);
166 
167 	snprintf(buf, sizeof buf, "%"PRIu16"?", v);
168 
169 	return (buf);
170 }
171 
172 const char *
173 typetostr(uint16_t v)
174 {
175 	static char	 buf[16];
176 	size_t		 i;
177 
178 	for(i = 0; kv_type[i].key; i++)
179 		if (kv_type[i].value == v)
180 			return (kv_type[i].key);
181 
182 	snprintf(buf, sizeof buf, "%"PRIu16"?", v);
183 
184 	return (buf);
185 }
186 
187 const char *
188 classtostr(uint16_t v)
189 {
190 	static char	 buf[16];
191 	size_t		 i;
192 
193 	for(i = 0; kv_class[i].key; i++)
194 		if (kv_class[i].value == v)
195 			return (kv_class[i].key);
196 
197 	snprintf(buf, sizeof buf, "%"PRIu16"?", v);
198 
199 	return (buf);
200 }
201 
202 uint16_t
203 strtotype(const char *name)
204 {
205 	size_t	i;
206 
207 	for(i = 0; kv_type[i].key; i++)
208 		if (!strcasecmp(kv_type[i].key, name))
209 			return (kv_type[i].value);
210 
211 	return (0);
212 }
213 
214 uint16_t
215 strtoclass(const char *name)
216 {
217 	size_t	i;
218 
219 	for(i = 0; kv_class[i].key; i++)
220 		if (!strcasecmp(kv_class[i].key, name))
221 			return (kv_class[i].value);
222 
223 	return (0);
224 }
225 
226 int
227 strtoresopt(const char *name)
228 {
229 	size_t	i;
230 
231 	for(i = 0; kv_resopt[i].key; i++)
232 		if (!strcasecmp(kv_resopt[i].key, name))
233 			return (kv_resopt[i].value);
234 
235 	return (0);
236 }
237 
238 void
239 parseresopt(const char *name)
240 {
241 	static int init = 0;
242 	int flag, neg = 0;
243 
244 	if (init == 0) {
245 		res_init();
246 		init = 1;
247 	}
248 
249 	if (name[0] == '-') {
250 		neg = 1;
251 		name++;
252 	}
253 	else if (name[0] == '+')
254 		name++;
255 
256 	flag = strtoresopt(name);
257 	if (flag == 0)
258 		errx(1, "unknown reslover option %s", name);
259 
260 	if (neg)
261 		_res.options &= ~flag;
262 	else
263 		_res.options |= flag;
264 }
265 
266 void
267 print_hostent(struct hostent *e)
268 {
269 	char	buf[256], **c;
270 
271 	printf("name = \"%s\"\n", e->h_name);
272 	printf("aliases =");
273 	for(c = e->h_aliases; *c; c++)
274 		printf(" \"%s\"", *c);
275 	printf("\n");
276 	printf("addrtype = %i\n", e->h_addrtype);
277 	printf("addrlength = %i\n", e->h_length);
278 	printf("addr_list =");
279 	for(c = e->h_addr_list; *c; c++) {
280 		printf(" %s", inet_ntop(e->h_addrtype, *c, buf, sizeof buf));
281 	}
282 	printf("\n");
283 }
284 
285 void
286 print_netent(struct netent *e)
287 {
288 	char	buf[256], **c;
289 	uint32_t addr;
290 
291 	/* network number are given in host order */
292 	addr = htonl(e->n_net);
293 
294 	printf("name = \"%s\"\n", e->n_name);
295 	printf("aliases =");
296 	for (c = e->n_aliases; *c; c++)
297 		printf(" \"%s\"", *c);
298 	printf("\n");
299 	printf("addrtype = %i\n", e->n_addrtype);
300 	printf("net = %s\n", inet_ntop(e->n_addrtype, &addr, buf, sizeof buf));
301 }
302 
303 void
304 print_addrinfo(struct addrinfo *ai)
305 {
306 	char	buf[256], bf[64], bt[64], bp[64];
307 
308 	printf("family=%s socktype=%s protocol=%s addr=%s canonname=%s\n",
309 		kv_lookup_name(kv_family, ai->ai_family, bf, sizeof bf),
310 		kv_lookup_name(kv_socktype, ai->ai_socktype, bt, sizeof bt),
311 		kv_lookup_name(kv_protocol, ai->ai_protocol, bp, sizeof bp),
312 		print_addr(ai->ai_addr, buf, sizeof buf),
313 		ai->ai_canonname);
314 }
315 
316 const char *
317 rrsetstrerror(int e)
318 {
319 	switch (e) {
320 	case 0:
321 		return "OK";
322 	case ERRSET_NONAME:
323 		return "ERRSET_NONAME";
324 	case ERRSET_NODATA:
325 		return "ERRSET_NODATA";
326 	case ERRSET_NOMEMORY:
327 		return "ERRSET_NOMEMORY";
328 	case ERRSET_INVAL:
329 		return "ERRSET_INVAL";
330 	case ERRSET_FAIL:
331 		return "ERRSET_FAIL";
332 	default:
333 		return "???";
334 	}
335 }
336 
337 void
338 print_rrsetinfo(struct rrsetinfo * rrset)
339 {
340 	printf("rri_flags=%u\n", rrset->rri_flags);
341 	printf("rri_rdclass=%u\n", rrset->rri_rdclass);
342 	printf("rri_rdtype=%u\n", rrset->rri_rdtype);
343 	printf("rri_ttl=%u\n", rrset->rri_ttl);
344 	printf("rri_nrdatas=%u\n", rrset->rri_nrdatas);
345 	printf("rri_nsigs=%u\n", rrset->rri_nsigs);
346 	printf("rri_name=\"%s\"\n", rrset->rri_name);
347 }
348 
349 void
350 print_errors(void)
351 {
352 	switch (long_err) {
353 	case 0:
354 		return;
355 	case 1:
356 		printf("  => errno %i, h_errno %i", errno, h_errno);
357 		printf(", rrset_errno %i", rrset_errno);
358 		printf(", gai_errno %i", gai_errno);
359 		printf ("\n");
360 		return;
361 	default:
362 		printf("  => errno %i: %s\n  => h_errno %i: %s\n  => rrset_errno %i: %s\n",
363 		    errno, errno ? strerror(errno) : "ok",
364 		    h_errno, h_errno ? hstrerror(h_errno) : "ok",
365 		    rrset_errno, rrset_errno ? rrsetstrerror(rrset_errno) : "ok");
366 		printf("  => gai_errno %i: %s\n",
367 		    gai_errno, gai_errno ? gai_strerror(gai_errno) : "ok");
368 	}
369 }
370 
371 
372 static char *
373 print_host(const struct sockaddr *sa, char *buf, size_t len)
374 {
375 	switch (sa->sa_family) {
376 	case AF_INET:
377 		inet_ntop(AF_INET, &((struct sockaddr_in*)sa)->sin_addr,
378 			  buf, len);
379 		break;
380 	case AF_INET6:
381 		inet_ntop(AF_INET6, &((struct sockaddr_in6*)sa)->sin6_addr,
382 			  buf, len);
383 		break;
384 	default:
385 		buf[0] = '\0';
386 	}
387 	return (buf);
388 }
389 
390 
391 char *
392 print_addr(const struct sockaddr *sa, char *buf, size_t len)
393 {
394 	char	h[256];
395 
396 	print_host(sa, h, sizeof h);
397 
398 	switch (sa->sa_family) {
399 	case AF_INET:
400 		snprintf(buf, len, "%s:%i", h,
401 		    ntohs(((struct sockaddr_in*)(sa))->sin_port));
402 		break;
403 	case AF_INET6:
404 		snprintf(buf, len, "[%s]:%i", h,
405 		    ntohs(((struct sockaddr_in6*)(sa))->sin6_port));
406 		break;
407 	default:
408 		snprintf(buf, len, "?");
409 		break;
410 	}
411 
412 	return (buf);
413 }
414 
415 void
416 packed_init(struct packed *pack, char *data, size_t len)
417 {
418 	pack->data = data;
419 	pack->len = len;
420 	pack->offset = 0;
421 	pack->err = NULL;
422 }
423 
424 
425 static ssize_t
426 dname_expand(const unsigned char *data, size_t len, size_t offset,
427     size_t *newoffset, char *dst, size_t max)
428 {
429 	size_t		 n, count, end, ptr, start;
430 	ssize_t		 res;
431 
432 	if (offset >= len)
433 		return (-1);
434 
435 	res = 0;
436 	end = start = offset;
437 
438 	for(; (n = data[offset]); ) {
439 		if ((n & 0xc0) == 0xc0) {
440 			if (offset + 2 > len)
441 				return (-1);
442 			ptr = 256 * (n & ~0xc0) + data[offset + 1];
443 			if (ptr >= start)
444 				return (-1);
445 			if (end < offset + 2)
446 				end = offset + 2;
447 			offset = ptr;
448 			continue;
449 		}
450 		if (offset + n + 1 > len)
451 			return (-1);
452 
453 
454 		/* copy n + at offset+1 */
455 		if (dst != NULL && max != 0) {
456 			count = (max < n + 1) ? (max) : (n + 1);
457 			memmove(dst, data + offset, count);
458 			dst += count;
459 			max -= count;
460 		}
461 		res += n + 1;
462 		offset += n + 1;
463 		if (end < offset)
464 			end = offset;
465 	}
466 	if (end < offset + 1)
467 		end = offset + 1;
468 
469 	if (dst != NULL && max != 0)
470 		dst[0] = 0;
471 	if (newoffset)
472 		*newoffset = end;
473 	return (res + 1);
474 }
475 
476 static int
477 unpack_data(struct packed *p, void *data, size_t len)
478 {
479 	if (p->err)
480 		return (-1);
481 
482 	if (p->len - p->offset < len) {
483 		p->err = "too short";
484 		return (-1);
485 	}
486 
487 	memmove(data, p->data + p->offset, len);
488 	p->offset += len;
489 
490 	return (0);
491 }
492 
493 static int
494 unpack_u16(struct packed *p, uint16_t *u16)
495 {
496 	if (unpack_data(p, u16, 2) == -1)
497 		return (-1);
498 
499 	*u16 = ntohs(*u16);
500 
501 	return (0);
502 }
503 
504 static int
505 unpack_u32(struct packed *p, uint32_t *u32)
506 {
507 	if (unpack_data(p, u32, 4) == -1)
508 		return (-1);
509 
510 	*u32 = ntohl(*u32);
511 
512 	return (0);
513 }
514 
515 static int
516 unpack_inaddr(struct packed *p, struct in_addr *a)
517 {
518 	return (unpack_data(p, a, 4));
519 }
520 
521 static int
522 unpack_in6addr(struct packed *p, struct in6_addr *a6)
523 {
524 	return (unpack_data(p, a6, 16));
525 }
526 
527 static int
528 unpack_dname(struct packed *p, char *dst, size_t max)
529 {
530 	ssize_t e;
531 
532 	if (p->err)
533 		return (-1);
534 
535 	e = dname_expand(p->data, p->len, p->offset, &p->offset, dst, max);
536 	if (e == -1) {
537 		p->err = "bad domain name";
538 		return (-1);
539 	}
540 	if (e < 0 || e > MAXDNAME) {
541 		p->err = "domain name too long";
542 		return (-1);
543 	}
544 
545 	return (0);
546 }
547 
548 int
549 unpack_header(struct packed *p, struct header *h)
550 {
551 	if (unpack_data(p, h, HFIXEDSZ) == -1)
552 		return (-1);
553 
554 	h->flags = ntohs(h->flags);
555 	h->qdcount = ntohs(h->qdcount);
556 	h->ancount = ntohs(h->ancount);
557 	h->nscount = ntohs(h->nscount);
558 	h->arcount = ntohs(h->arcount);
559 
560 	return (0);
561 }
562 
563 int
564 unpack_query(struct packed *p, struct query *q)
565 {
566 	unpack_dname(p, q->q_dname, sizeof(q->q_dname));
567 	unpack_u16(p, &q->q_type);
568 	unpack_u16(p, &q->q_class);
569 
570 	return (p->err) ? (-1) : (0);
571 }
572 
573 int
574 unpack_rr(struct packed *p, struct rr *rr)
575 {
576 	uint16_t	rdlen;
577 	size_t		save_offset;
578 
579 	unpack_dname(p, rr->rr_dname, sizeof(rr->rr_dname));
580 	unpack_u16(p, &rr->rr_type);
581 	unpack_u16(p, &rr->rr_class);
582 	unpack_u32(p, &rr->rr_ttl);
583 	unpack_u16(p, &rdlen);
584 
585 	if (p->err)
586 		return (-1);
587 
588 	if (p->len - p->offset < rdlen) {
589 		p->err = "too short";
590 		return (-1);
591 	}
592 
593 	save_offset = p->offset;
594 
595 	switch(rr->rr_type) {
596 
597 	case T_CNAME:
598 		unpack_dname(p, rr->rr.cname.cname, sizeof(rr->rr.cname.cname));
599 		break;
600 
601 	case T_MX:
602 		unpack_u16(p, &rr->rr.mx.preference);
603 		unpack_dname(p, rr->rr.mx.exchange, sizeof(rr->rr.mx.exchange));
604 		break;
605 
606 	case T_NS:
607 		unpack_dname(p, rr->rr.ns.nsname, sizeof(rr->rr.ns.nsname));
608 		break;
609 
610 	case T_PTR:
611 		unpack_dname(p, rr->rr.ptr.ptrname, sizeof(rr->rr.ptr.ptrname));
612 		break;
613 
614 	case T_SOA:
615 		unpack_dname(p, rr->rr.soa.mname, sizeof(rr->rr.soa.mname));
616 		unpack_dname(p, rr->rr.soa.rname, sizeof(rr->rr.soa.rname));
617 		unpack_u32(p, &rr->rr.soa.serial);
618 		unpack_u32(p, &rr->rr.soa.refresh);
619 		unpack_u32(p, &rr->rr.soa.retry);
620 		unpack_u32(p, &rr->rr.soa.expire);
621 		unpack_u32(p, &rr->rr.soa.minimum);
622 		break;
623 
624 	case T_A:
625 		if (rr->rr_class != C_IN)
626 			goto other;
627 		unpack_inaddr(p, &rr->rr.in_a.addr);
628 		break;
629 
630 	case T_AAAA:
631 		if (rr->rr_class != C_IN)
632 			goto other;
633 		unpack_in6addr(p, &rr->rr.in_aaaa.addr6);
634 		break;
635 	default:
636 	other:
637 		rr->rr.other.rdata = p->data + p->offset;
638 		rr->rr.other.rdlen = rdlen;
639 		p->offset += rdlen;
640 	}
641 
642 	if (p->err)
643 		return (-1);
644 
645 	/* make sure that the advertised rdlen is really ok */
646 	if (p->offset - save_offset != rdlen)
647 		p->err = "bad dlen";
648 
649 	return (p->err) ? (-1) : (0);
650 }
651 
652 int
653 sockaddr_from_str(struct sockaddr *sa, int family, const char *str)
654 {
655 	struct in_addr		 ina;
656 	struct in6_addr		 in6a;
657 	struct sockaddr_in	*sin;
658 	struct sockaddr_in6	*sin6;
659 
660 	switch (family) {
661 	case PF_UNSPEC:
662 		if (sockaddr_from_str(sa, PF_INET, str) == 0)
663 			return (0);
664 		return sockaddr_from_str(sa, PF_INET6, str);
665 
666 	case PF_INET:
667 		if (inet_pton(PF_INET, str, &ina) != 1)
668 			return (-1);
669 
670 		sin = (struct sockaddr_in *)sa;
671 		memset(sin, 0, sizeof *sin);
672 		sin->sin_len = sizeof(struct sockaddr_in);
673 		sin->sin_family = PF_INET;
674 		sin->sin_addr.s_addr = ina.s_addr;
675 		return (0);
676 
677 	case PF_INET6:
678 		if (inet_pton(PF_INET6, str, &in6a) != 1)
679 			return (-1);
680 
681 		sin6 = (struct sockaddr_in6 *)sa;
682 		memset(sin6, 0, sizeof *sin6);
683 		sin6->sin6_len = sizeof(struct sockaddr_in6);
684 		sin6->sin6_family = PF_INET6;
685 		sin6->sin6_addr = in6a;
686 		return (0);
687 
688 	default:
689 		break;
690 	}
691 
692 	return (-1);
693 }
694