diff options
Diffstat (limited to 'src/regress/lib/libc/asr/bin/common.c')
-rw-r--r-- | src/regress/lib/libc/asr/bin/common.c | 693 |
1 files changed, 0 insertions, 693 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 08a7bccbb7..0000000000 --- a/src/regress/lib/libc/asr/bin/common.c +++ /dev/null | |||
@@ -1,693 +0,0 @@ | |||
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 | } | ||