summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/asr/bin/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libc/asr/bin/common.c')
-rw-r--r--src/regress/lib/libc/asr/bin/common.c635
1 files changed, 0 insertions, 635 deletions
diff --git a/src/regress/lib/libc/asr/bin/common.c b/src/regress/lib/libc/asr/bin/common.c
deleted file mode 100644
index c808c86d61..0000000000
--- a/src/regress/lib/libc/asr/bin/common.c
+++ /dev/null
@@ -1,635 +0,0 @@
1/* $OpenBSD: common.c,v 1.3 2014/08/10 07:31:58 guenther 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
33int long_err;
34int gai_errno;
35int rrset_errno;
36
37
38char *
39gethostarg(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
50const char *rrsetstrerror(int);
51char * print_addr(const struct sockaddr *, char *, size_t);
52
53struct kv { int code; const char *name; };
54
55struct kv kv_family[] = {
56 { AF_UNIX, "unix" },
57 { AF_INET, "inet" },
58 { AF_INET6, "inet6" },
59 { 0, NULL, }
60};
61struct kv kv_socktype[] = {
62 { SOCK_STREAM, "stream" },
63 { SOCK_DGRAM, "dgram" },
64 { SOCK_RAW, "raw" },
65 { SOCK_SEQPACKET, "seqpacket" },
66 { 0, NULL, }
67};
68struct kv kv_protocol[] = {
69 { IPPROTO_UDP, "udp" },
70 { IPPROTO_TCP, "tcp" },
71 { IPPROTO_ICMP, "icmp" },
72 { IPPROTO_ICMPV6, "icmpv6" },
73 { 0, NULL, }
74};
75
76static const char *
77kv_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
88struct keyval {
89 const char *key;
90 uint16_t value;
91};
92
93static 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
101static 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
128static 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
139const char *
140rcodetostr(uint16_t v)
141{
142 static char buf[16];
143 size_t i;
144
145 for(i = 0; kv_rcode[i].key; i++)
146 if (kv_rcode[i].value == v)
147 return (kv_rcode[i].key);
148
149 snprintf(buf, sizeof buf, "%"PRIu16"?", v);
150
151 return (buf);
152}
153
154const char *
155typetostr(uint16_t v)
156{
157 static char buf[16];
158 size_t i;
159
160 for(i = 0; kv_type[i].key; i++)
161 if (kv_type[i].value == v)
162 return (kv_type[i].key);
163
164 snprintf(buf, sizeof buf, "%"PRIu16"?", v);
165
166 return (buf);
167}
168
169const char *
170classtostr(uint16_t v)
171{
172 static char buf[16];
173 size_t i;
174
175 for(i = 0; kv_class[i].key; i++)
176 if (kv_class[i].value == v)
177 return (kv_class[i].key);
178
179 snprintf(buf, sizeof buf, "%"PRIu16"?", v);
180
181 return (buf);
182}
183
184uint16_t
185strtotype(const char *name)
186{
187 size_t i;
188
189 for(i = 0; kv_type[i].key; i++)
190 if (!strcmp(kv_type[i].key, name))
191 return (kv_type[i].value);
192
193 return (0);
194}
195
196uint16_t
197strtoclass(const char *name)
198{
199 size_t i;
200
201 for(i = 0; kv_class[i].key; i++)
202 if (!strcmp(kv_class[i].key, name))
203 return (kv_class[i].value);
204
205 return (0);
206}
207
208void
209print_hostent(struct hostent *e)
210{
211 char buf[256], **c;
212
213 printf("name = \"%s\"\n", e->h_name);
214 printf("aliases =");
215 for(c = e->h_aliases; *c; c++)
216 printf(" \"%s\"", *c);
217 printf("\n");
218 printf("addrtype = %i\n", e->h_addrtype);
219 printf("addrlength = %i\n", e->h_length);
220 printf("addr_list =");
221 for(c = e->h_addr_list; *c; c++) {
222 printf(" %s", inet_ntop(e->h_addrtype, *c, buf, sizeof buf));
223 }
224 printf("\n");
225}
226
227void
228print_netent(struct netent *e)
229{
230 char buf[256], **c;
231 uint32_t addr;
232
233 /* network number are given in host order */
234 addr = htonl(e->n_net);
235
236 printf("name = \"%s\"\n", e->n_name);
237 printf("aliases =");
238 for (c = e->n_aliases; *c; c++)
239 printf(" \"%s\"", *c);
240 printf("\n");
241 printf("addrtype = %i\n", e->n_addrtype);
242 printf("net = %s\n", inet_ntop(e->n_addrtype, &addr, buf, sizeof buf));
243}
244
245void
246print_addrinfo(struct addrinfo *ai)
247{
248 char buf[256], bf[64], bt[64], bp[64];
249
250 printf("family=%s socktype=%s protocol=%s addr=%s canonname=%s\n",
251 kv_lookup_name(kv_family, ai->ai_family, bf, sizeof bf),
252 kv_lookup_name(kv_socktype, ai->ai_socktype, bt, sizeof bt),
253 kv_lookup_name(kv_protocol, ai->ai_protocol, bp, sizeof bp),
254 print_addr(ai->ai_addr, buf, sizeof buf),
255 ai->ai_canonname);
256}
257
258const char *
259rrsetstrerror(int e)
260{
261 switch (e) {
262 case 0:
263 return "OK";
264 case ERRSET_NONAME:
265 return "ERRSET_NONAME";
266 case ERRSET_NODATA:
267 return "ERRSET_NODATA";
268 case ERRSET_NOMEMORY:
269 return "ERRSET_NOMEMORY";
270 case ERRSET_INVAL:
271 return "ERRSET_INVAL";
272 case ERRSET_FAIL:
273 return "ERRSET_FAIL";
274 default:
275 return "???";
276 }
277}
278
279void
280print_rrsetinfo(struct rrsetinfo * rrset)
281{
282 printf("rri_flags=%u\n", rrset->rri_flags);
283 printf("rri_rdclass=%u\n", rrset->rri_rdclass);
284 printf("rri_rdtype=%u\n", rrset->rri_rdtype);
285 printf("rri_ttl=%u\n", rrset->rri_ttl);
286 printf("rri_nrdatas=%u\n", rrset->rri_nrdatas);
287 printf("rri_nsigs=%u\n", rrset->rri_nsigs);
288 printf("rri_name=\"%s\"\n", rrset->rri_name);
289}
290
291void
292print_errors(void)
293{
294 switch (long_err) {
295 case 0:
296 return;
297 case 1:
298 printf(" => errno %i, h_errno %i", errno, h_errno);
299 printf(", rrset_errno %i", rrset_errno);
300 printf(", gai_errno %i", gai_errno);
301 printf ("\n");
302 return;
303 default:
304 printf(" => errno %i: %s\n => h_errno %i: %s\n => rrset_errno %i: %s\n",
305 errno, errno ? strerror(errno) : "ok",
306 h_errno, h_errno ? hstrerror(h_errno) : "ok",
307 rrset_errno, rrset_errno ? rrsetstrerror(rrset_errno) : "ok");
308 printf(" => gai_errno %i: %s\n",
309 gai_errno, gai_errno ? gai_strerror(gai_errno) : "ok");
310 }
311}
312
313
314static char *
315print_host(const struct sockaddr *sa, char *buf, size_t len)
316{
317 switch (sa->sa_family) {
318 case AF_INET:
319 inet_ntop(AF_INET, &((struct sockaddr_in*)sa)->sin_addr,
320 buf, len);
321 break;
322 case AF_INET6:
323 inet_ntop(AF_INET6, &((struct sockaddr_in6*)sa)->sin6_addr,
324 buf, len);
325 break;
326 default:
327 buf[0] = '\0';
328 }
329 return (buf);
330}
331
332
333char *
334print_addr(const struct sockaddr *sa, char *buf, size_t len)
335{
336 char h[256];
337
338 print_host(sa, h, sizeof h);
339
340 switch (sa->sa_family) {
341 case AF_INET:
342 snprintf(buf, len, "%s:%i", h,
343 ntohs(((struct sockaddr_in*)(sa))->sin_port));
344 break;
345 case AF_INET6:
346 snprintf(buf, len, "[%s]:%i", h,
347 ntohs(((struct sockaddr_in6*)(sa))->sin6_port));
348 break;
349 default:
350 snprintf(buf, len, "?");
351 break;
352 }
353
354 return (buf);
355}
356
357void
358packed_init(struct packed *pack, char *data, size_t len)
359{
360 pack->data = data;
361 pack->len = len;
362 pack->offset = 0;
363 pack->err = NULL;
364}
365
366
367static ssize_t
368dname_expand(const unsigned char *data, size_t len, size_t offset,
369 size_t *newoffset, char *dst, size_t max)
370{
371 size_t n, count, end, ptr, start;
372 ssize_t res;
373
374 if (offset >= len)
375 return (-1);
376
377 res = 0;
378 end = start = offset;
379
380 for(; (n = data[offset]); ) {
381 if ((n & 0xc0) == 0xc0) {
382 if (offset + 2 > len)
383 return (-1);
384 ptr = 256 * (n & ~0xc0) + data[offset + 1];
385 if (ptr >= start)
386 return (-1);
387 if (end < offset + 2)
388 end = offset + 2;
389 offset = ptr;
390 continue;
391 }
392 if (offset + n + 1 > len)
393 return (-1);
394
395
396 /* copy n + at offset+1 */
397 if (dst != NULL && max != 0) {
398 count = (max < n + 1) ? (max) : (n + 1);
399 memmove(dst, data + offset, count);
400 dst += count;
401 max -= count;
402 }
403 res += n + 1;
404 offset += n + 1;
405 if (end < offset)
406 end = offset;
407 }
408 if (end < offset + 1)
409 end = offset + 1;
410
411 if (dst != NULL && max != 0)
412 dst[0] = 0;
413 if (newoffset)
414 *newoffset = end;
415 return (res + 1);
416}
417
418static int
419unpack_data(struct packed *p, void *data, size_t len)
420{
421 if (p->err)
422 return (-1);
423
424 if (p->len - p->offset < len) {
425 p->err = "too short";
426 return (-1);
427 }
428
429 memmove(data, p->data + p->offset, len);
430 p->offset += len;
431
432 return (0);
433}
434
435static int
436unpack_u16(struct packed *p, uint16_t *u16)
437{
438 if (unpack_data(p, u16, 2) == -1)
439 return (-1);
440
441 *u16 = ntohs(*u16);
442
443 return (0);
444}
445
446static int
447unpack_u32(struct packed *p, uint32_t *u32)
448{
449 if (unpack_data(p, u32, 4) == -1)
450 return (-1);
451
452 *u32 = ntohl(*u32);
453
454 return (0);
455}
456
457static int
458unpack_inaddr(struct packed *p, struct in_addr *a)
459{
460 return (unpack_data(p, a, 4));
461}
462
463static int
464unpack_in6addr(struct packed *p, struct in6_addr *a6)
465{
466 return (unpack_data(p, a6, 16));
467}
468
469static int
470unpack_dname(struct packed *p, char *dst, size_t max)
471{
472 ssize_t e;
473
474 if (p->err)
475 return (-1);
476
477 e = dname_expand(p->data, p->len, p->offset, &p->offset, dst, max);
478 if (e == -1) {
479 p->err = "bad domain name";
480 return (-1);
481 }
482 if (e < 0 || e > MAXDNAME) {
483 p->err = "domain name too long";
484 return (-1);
485 }
486
487 return (0);
488}
489
490int
491unpack_header(struct packed *p, struct header *h)
492{
493 if (unpack_data(p, h, HFIXEDSZ) == -1)
494 return (-1);
495
496 h->flags = ntohs(h->flags);
497 h->qdcount = ntohs(h->qdcount);
498 h->ancount = ntohs(h->ancount);
499 h->nscount = ntohs(h->nscount);
500 h->arcount = ntohs(h->arcount);
501
502 return (0);
503}
504
505int
506unpack_query(struct packed *p, struct query *q)
507{
508 unpack_dname(p, q->q_dname, sizeof(q->q_dname));
509 unpack_u16(p, &q->q_type);
510 unpack_u16(p, &q->q_class);
511
512 return (p->err) ? (-1) : (0);
513}
514
515int
516unpack_rr(struct packed *p, struct rr *rr)
517{
518 uint16_t rdlen;
519 size_t save_offset;
520
521 unpack_dname(p, rr->rr_dname, sizeof(rr->rr_dname));
522 unpack_u16(p, &rr->rr_type);
523 unpack_u16(p, &rr->rr_class);
524 unpack_u32(p, &rr->rr_ttl);
525 unpack_u16(p, &rdlen);
526
527 if (p->err)
528 return (-1);
529
530 if (p->len - p->offset < rdlen) {
531 p->err = "too short";
532 return (-1);
533 }
534
535 save_offset = p->offset;
536
537 switch(rr->rr_type) {
538
539 case T_CNAME:
540 unpack_dname(p, rr->rr.cname.cname, sizeof(rr->rr.cname.cname));
541 break;
542
543 case T_MX:
544 unpack_u16(p, &rr->rr.mx.preference);
545 unpack_dname(p, rr->rr.mx.exchange, sizeof(rr->rr.mx.exchange));
546 break;
547
548 case T_NS:
549 unpack_dname(p, rr->rr.ns.nsname, sizeof(rr->rr.ns.nsname));
550 break;
551
552 case T_PTR:
553 unpack_dname(p, rr->rr.ptr.ptrname, sizeof(rr->rr.ptr.ptrname));
554 break;
555
556 case T_SOA:
557 unpack_dname(p, rr->rr.soa.mname, sizeof(rr->rr.soa.mname));
558 unpack_dname(p, rr->rr.soa.rname, sizeof(rr->rr.soa.rname));
559 unpack_u32(p, &rr->rr.soa.serial);
560 unpack_u32(p, &rr->rr.soa.refresh);
561 unpack_u32(p, &rr->rr.soa.retry);
562 unpack_u32(p, &rr->rr.soa.expire);
563 unpack_u32(p, &rr->rr.soa.minimum);
564 break;
565
566 case T_A:
567 if (rr->rr_class != C_IN)
568 goto other;
569 unpack_inaddr(p, &rr->rr.in_a.addr);
570 break;
571
572 case T_AAAA:
573 if (rr->rr_class != C_IN)
574 goto other;
575 unpack_in6addr(p, &rr->rr.in_aaaa.addr6);
576 break;
577 default:
578 other:
579 rr->rr.other.rdata = p->data + p->offset;
580 rr->rr.other.rdlen = rdlen;
581 p->offset += rdlen;
582 }
583
584 if (p->err)
585 return (-1);
586
587 /* make sure that the advertised rdlen is really ok */
588 if (p->offset - save_offset != rdlen)
589 p->err = "bad dlen";
590
591 return (p->err) ? (-1) : (0);
592}
593
594int
595sockaddr_from_str(struct sockaddr *sa, int family, const char *str)
596{
597 struct in_addr ina;
598 struct in6_addr in6a;
599 struct sockaddr_in *sin;
600 struct sockaddr_in6 *sin6;
601
602 switch (family) {
603 case PF_UNSPEC:
604 if (sockaddr_from_str(sa, PF_INET, str) == 0)
605 return (0);
606 return sockaddr_from_str(sa, PF_INET6, str);
607
608 case PF_INET:
609 if (inet_pton(PF_INET, str, &ina) != 1)
610 return (-1);
611
612 sin = (struct sockaddr_in *)sa;
613 memset(sin, 0, sizeof *sin);
614 sin->sin_len = sizeof(struct sockaddr_in);
615 sin->sin_family = PF_INET;
616 sin->sin_addr.s_addr = ina.s_addr;
617 return (0);
618
619 case PF_INET6:
620 if (inet_pton(PF_INET6, str, &in6a) != 1)
621 return (-1);
622
623 sin6 = (struct sockaddr_in6 *)sa;
624 memset(sin6, 0, sizeof *sin6);
625 sin6->sin6_len = sizeof(struct sockaddr_in6);
626 sin6->sin6_family = PF_INET6;
627 sin6->sin6_addr = in6a;
628 return (0);
629
630 default:
631 break;
632 }
633
634 return (-1);
635}