summaryrefslogtreecommitdiff
path: root/sbin/unwind
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/unwind')
-rw-r--r--sbin/unwind/Makefile3
-rw-r--r--sbin/unwind/asr_private.h299
-rw-r--r--sbin/unwind/asr_utils.c663
-rw-r--r--sbin/unwind/frontend.c129
-rw-r--r--sbin/unwind/resolver.c53
5 files changed, 103 insertions, 1044 deletions
diff --git a/sbin/unwind/Makefile b/sbin/unwind/Makefile
index b20ac0ed9fc..245c528ffbb 100644
--- a/sbin/unwind/Makefile
+++ b/sbin/unwind/Makefile
@@ -1,8 +1,7 @@
-# $OpenBSD: Makefile,v 1.1 2019/01/23 13:11:00 florian Exp $
+# $OpenBSD: Makefile,v 1.2 2019/01/24 15:33:44 florian Exp $
PROG= unwind
SRCS= control.c resolver.c frontend.c uw_log.c unwind.c uw_parse.y printconf.c
-SRCS+= asr_utils.c
MAN= unwind.8 unwind.conf.5
.include "${.CURDIR}/libunbound/Makefile.inc"
diff --git a/sbin/unwind/asr_private.h b/sbin/unwind/asr_private.h
deleted file mode 100644
index d18acb01d1d..00000000000
--- a/sbin/unwind/asr_private.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/* $OpenBSD: asr_private.h,v 1.1 2019/01/23 13:11:00 florian Exp $ */
-/*
- * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define QR_MASK (0x1 << 15)
-#define OPCODE_MASK (0xf << 11)
-#define AA_MASK (0x1 << 10)
-#define TC_MASK (0x1 << 9)
-#define RD_MASK (0x1 << 8)
-#define RA_MASK (0x1 << 7)
-#define Z_MASK (0x1 << 6)
-#define AD_MASK (0x1 << 5)
-#define CD_MASK (0x1 << 4)
-#define RCODE_MASK (0xf)
-
-#define OPCODE(v) ((v) & OPCODE_MASK)
-#define RCODE(v) ((v) & RCODE_MASK)
-
-struct asr_pack {
- char *buf;
- size_t len;
- size_t offset;
- int err;
-};
-
-struct asr_unpack {
- const char *buf;
- size_t len;
- size_t offset;
- int err;
-};
-
-struct asr_dns_header {
- uint16_t id;
- uint16_t flags;
- uint16_t qdcount;
- uint16_t ancount;
- uint16_t nscount;
- uint16_t arcount;
-};
-
-struct asr_dns_query {
- char q_dname[MAXDNAME];
- uint16_t q_type;
- uint16_t q_class;
-};
-
-struct asr_dns_rr {
- char rr_dname[MAXDNAME];
- uint16_t rr_type;
- uint16_t rr_class;
- uint32_t rr_ttl;
- union {
- struct {
- char cname[MAXDNAME];
- } cname;
- struct {
- uint16_t preference;
- char exchange[MAXDNAME];
- } mx;
- struct {
- char nsname[MAXDNAME];
- } ns;
- struct {
- char ptrname[MAXDNAME];
- } ptr;
- struct {
- char mname[MAXDNAME];
- char rname[MAXDNAME];
- uint32_t serial;
- uint32_t refresh;
- uint32_t retry;
- uint32_t expire;
- uint32_t minimum;
- } soa;
- struct {
- struct in_addr addr;
- } in_a;
- struct {
- struct in6_addr addr6;
- } in_aaaa;
- struct {
- uint16_t rdlen;
- const void *rdata;
- } other;
- } rr;
-};
-
-
-#define ASR_MAXNS 5
-#define ASR_MAXDB 3
-#define ASR_MAXDOM 10
-
-enum async_type {
- ASR_SEND,
- ASR_SEARCH,
- ASR_GETRRSETBYNAME,
- ASR_GETHOSTBYNAME,
- ASR_GETHOSTBYADDR,
- ASR_GETADDRINFO,
- ASR_GETNAMEINFO,
-};
-
-#define ASR_DB_FILE 'f'
-#define ASR_DB_DNS 'b'
-
-struct asr_ctx {
- int ac_refcount;
- int ac_options;
- int ac_ndots;
- char *ac_domain;
- int ac_domcount;
- char *ac_dom[ASR_MAXDOM];
- int ac_dbcount;
- char ac_db[ASR_MAXDB + 1];
- int ac_family[3];
-
- int ac_nscount;
- int ac_nstimeout;
- int ac_nsretries;
- struct sockaddr *ac_ns[ASR_MAXNS];
-
-};
-
-struct asr {
- pid_t a_pid;
- time_t a_mtime;
- time_t a_rtime;
- struct asr_ctx *a_ctx;
-};
-
-#define ASYNC_COND 0
-#define ASYNC_DONE 1
-
-#define ASYNC_DOM_FQDN 0x00000001
-#define ASYNC_DOM_NDOTS 0x00000002
-#define ASYNC_DOM_DOMAIN 0x00000004
-#define ASYNC_DOM_ASIS 0x00000008
-
-#define ASYNC_NODATA 0x00000100
-#define ASYNC_AGAIN 0x00000200
-
-#define ASYNC_GETNET 0x00001000
-#define ASYNC_EXTOBUF 0x00002000
-
-#define ASYNC_NO_INET 0x00010000
-#define ASYNC_NO_INET6 0x00020000
-
-struct asr_query {
- int (*as_run)(struct asr_query *, struct asr_result *);
- struct asr_ctx *as_ctx;
- int as_type;
- int as_flags;
- int as_state;
-
- /* cond */
- int as_timeout;
- int as_fd;
- struct asr_query *as_subq;
-
- /* loop indices in ctx */
- int as_dom_step;
- int as_dom_idx;
- int as_dom_flags;
- int as_family_idx;
- int as_db_idx;
-
- int as_count;
-
- union {
- struct {
- uint16_t reqid;
- int class;
- int type;
- char *dname; /* not fqdn! */
- int rcode; /* response code */
- int ancount; /* answer count */
-
- int nsidx;
- int nsloop;
-
- /* io buffers for query/response */
- unsigned char *obuf;
- size_t obuflen;
- size_t obufsize;
- unsigned char *ibuf;
- size_t ibuflen;
- size_t ibufsize;
- size_t datalen; /* for tcp io */
- uint16_t pktlen;
- } dns;
-
- struct {
- int class;
- int type;
- char *name;
- int saved_h_errno;
- } search;
-
- struct {
- int flags;
- int class;
- int type;
- char *name;
- } rrset;
-
- struct {
- char *name;
- int family;
- char addr[16];
- int addrlen;
- int subq_h_errno;
- } hostnamadr;
-
- struct {
- char *hostname;
- char *servname;
- int port_tcp;
- int port_udp;
- union {
- struct sockaddr sa;
- struct sockaddr_in sain;
- struct sockaddr_in6 sain6;
- } sa;
-
- struct addrinfo hints;
- char *fqdn;
- struct addrinfo *aifirst;
- struct addrinfo *ailast;
- } ai;
-
- struct {
- char *hostname;
- char *servname;
- size_t hostnamelen;
- size_t servnamelen;
- union {
- struct sockaddr sa;
- struct sockaddr_in sain;
- struct sockaddr_in6 sain6;
- } sa;
- int flags;
- } ni;
-#define MAXTOKEN 10
- } as;
-
-};
-
-#define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1])
-#define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx])
-
-enum asr_state {
- ASR_STATE_INIT,
- ASR_STATE_NEXT_DOMAIN,
- ASR_STATE_NEXT_DB,
- ASR_STATE_SAME_DB,
- ASR_STATE_NEXT_FAMILY,
- ASR_STATE_NEXT_NS,
- ASR_STATE_UDP_SEND,
- ASR_STATE_UDP_RECV,
- ASR_STATE_TCP_WRITE,
- ASR_STATE_TCP_READ,
- ASR_STATE_PACKET,
- ASR_STATE_SUBQUERY,
- ASR_STATE_NOT_FOUND,
- ASR_STATE_HALT,
-};
-
-#define MAXPACKETSZ 4096
-
-/* asr_utils.c */
-void _asr_pack_init(struct asr_pack *, char *, size_t);
-int _asr_pack_header(struct asr_pack *, const struct asr_dns_header *);
-int _asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *);
-int _asr_pack_edns0(struct asr_pack *, uint16_t, int);
-void _asr_unpack_init(struct asr_unpack *, const char *, size_t);
-int _asr_unpack_header(struct asr_unpack *, struct asr_dns_header *);
-int _asr_unpack_query(struct asr_unpack *, struct asr_dns_query *);
-int _asr_unpack_rr(struct asr_unpack *, struct asr_dns_rr *);
-int _asr_sockaddr_from_str(struct sockaddr *, int, const char *);
-ssize_t _asr_dname_from_fqdn(const char *, char *, size_t);
-ssize_t _asr_addr_as_fqdn(const char *, int, char *, size_t);
-
-const char *print_dname(const char *, char *, size_t);
-const char *print_header(const struct asr_dns_header *, char *, size_t);
-const char *print_query(const struct asr_dns_query *, char *, size_t);
diff --git a/sbin/unwind/asr_utils.c b/sbin/unwind/asr_utils.c
deleted file mode 100644
index 94855ec61b6..00000000000
--- a/sbin/unwind/asr_utils.c
+++ /dev/null
@@ -1,663 +0,0 @@
-/* $OpenBSD: asr_utils.c,v 1.1 2019/01/23 13:11:00 florian Exp $ */
-/*
- * Copyright (c) 2009-2012 Eric Faurot <eric@faurot.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-
-#include <asr.h>
-#include <ctype.h>
-#include <errno.h>
-#include <resolv.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asr_private.h"
-
-static int dname_check_label(const char *, size_t);
-static ssize_t dname_expand(const unsigned char *, size_t, size_t, size_t *,
- char *, size_t);
-
-static int unpack_data(struct asr_unpack *, void *, size_t);
-static int unpack_u16(struct asr_unpack *, uint16_t *);
-static int unpack_u32(struct asr_unpack *, uint32_t *);
-static int unpack_inaddr(struct asr_unpack *, struct in_addr *);
-static int unpack_in6addr(struct asr_unpack *, struct in6_addr *);
-static int unpack_dname(struct asr_unpack *, char *, size_t);
-
-static int pack_data(struct asr_pack *, const void *, size_t);
-static int pack_u16(struct asr_pack *, uint16_t);
-static int pack_dname(struct asr_pack *, const char *);
-
-/* from asr_debug.c */
-static const char *rcodetostr(uint16_t);
-
-/* from asr.c */
-char * _asr_strdname(const char *, char *, size_t);
-
-static int
-dname_check_label(const char *s, size_t l)
-{
- if (l == 0 || l > 63)
- return (-1);
-
- return (0);
-}
-
-ssize_t
-_asr_dname_from_fqdn(const char *str, char *dst, size_t max)
-{
- ssize_t res;
- size_t l, n;
- char *d;
-
- res = 0;
-
- /* special case: the root domain */
- if (str[0] == '.') {
- if (str[1] != '\0')
- return (-1);
- if (dst && max >= 1)
- *dst = '\0';
- return (1);
- }
-
- for (; *str; str = d + 1) {
-
- d = strchr(str, '.');
- if (d == NULL || d == str)
- return (-1);
-
- l = (d - str);
-
- if (dname_check_label(str, l) == -1)
- return (-1);
-
- res += l + 1;
-
- if (dst) {
- *dst++ = l;
- max -= 1;
- n = (l > max) ? max : l;
- memmove(dst, str, n);
- max -= n;
- if (max == 0)
- dst = NULL;
- else
- dst += n;
- }
- }
-
- if (dst)
- *dst++ = '\0';
-
- return (res + 1);
-}
-
-static ssize_t
-dname_expand(const unsigned char *data, size_t len, size_t offset,
- size_t *newoffset, char *dst, size_t max)
-{
- size_t n, count, end, ptr, start;
- ssize_t res;
-
- if (offset >= len)
- return (-1);
-
- res = 0;
- end = start = offset;
-
- for (; (n = data[offset]); ) {
- if ((n & 0xc0) == 0xc0) {
- if (offset + 2 > len)
- return (-1);
- ptr = 256 * (n & ~0xc0) + data[offset + 1];
- if (ptr >= start)
- return (-1);
- if (end < offset + 2)
- end = offset + 2;
- offset = start = ptr;
- continue;
- }
- if (offset + n + 1 > len)
- return (-1);
-
- if (dname_check_label(data + offset + 1, n) == -1)
- return (-1);
-
- /* copy n + at offset+1 */
- if (dst != NULL && max != 0) {
- count = (max < n + 1) ? (max) : (n + 1);
- memmove(dst, data + offset, count);
- dst += count;
- max -= count;
- }
- res += n + 1;
- offset += n + 1;
- if (end < offset)
- end = offset;
- }
- if (end < offset + 1)
- end = offset + 1;
-
- if (dst != NULL && max != 0)
- dst[0] = 0;
- if (newoffset)
- *newoffset = end;
- return (res + 1);
-}
-
-void
-_asr_pack_init(struct asr_pack *pack, char *buf, size_t len)
-{
- pack->buf = buf;
- pack->len = len;
- pack->offset = 0;
- pack->err = 0;
-}
-
-void
-_asr_unpack_init(struct asr_unpack *unpack, const char *buf, size_t len)
-{
- unpack->buf = buf;
- unpack->len = len;
- unpack->offset = 0;
- unpack->err = 0;
-}
-
-static int
-unpack_data(struct asr_unpack *p, void *data, size_t len)
-{
- if (p->err)
- return (-1);
-
- if (p->len - p->offset < len) {
- p->err = EOVERFLOW;
- return (-1);
- }
-
- memmove(data, p->buf + p->offset, len);
- p->offset += len;
-
- return (0);
-}
-
-static int
-unpack_u16(struct asr_unpack *p, uint16_t *u16)
-{
- if (unpack_data(p, u16, 2) == -1)
- return (-1);
-
- *u16 = ntohs(*u16);
-
- return (0);
-}
-
-static int
-unpack_u32(struct asr_unpack *p, uint32_t *u32)
-{
- if (unpack_data(p, u32, 4) == -1)
- return (-1);
-
- *u32 = ntohl(*u32);
-
- return (0);
-}
-
-static int
-unpack_inaddr(struct asr_unpack *p, struct in_addr *a)
-{
- return (unpack_data(p, a, 4));
-}
-
-static int
-unpack_in6addr(struct asr_unpack *p, struct in6_addr *a6)
-{
- return (unpack_data(p, a6, 16));
-}
-
-static int
-unpack_dname(struct asr_unpack *p, char *dst, size_t max)
-{
- ssize_t e;
-
- if (p->err)
- return (-1);
-
- e = dname_expand(p->buf, p->len, p->offset, &p->offset, dst, max);
- if (e == -1) {
- p->err = EINVAL;
- return (-1);
- }
- if (e < 0 || e > MAXDNAME) {
- p->err = ERANGE;
- return (-1);
- }
-
- return (0);
-}
-
-int
-_asr_unpack_header(struct asr_unpack *p, struct asr_dns_header *h)
-{
- if (unpack_data(p, h, HFIXEDSZ) == -1)
- return (-1);
-
- h->flags = ntohs(h->flags);
- h->qdcount = ntohs(h->qdcount);
- h->ancount = ntohs(h->ancount);
- h->nscount = ntohs(h->nscount);
- h->arcount = ntohs(h->arcount);
-
- return (0);
-}
-
-int
-_asr_unpack_query(struct asr_unpack *p, struct asr_dns_query *q)
-{
- unpack_dname(p, q->q_dname, sizeof(q->q_dname));
- unpack_u16(p, &q->q_type);
- unpack_u16(p, &q->q_class);
-
- return (p->err) ? (-1) : (0);
-}
-
-int
-_asr_unpack_rr(struct asr_unpack *p, struct asr_dns_rr *rr)
-{
- uint16_t rdlen;
- size_t save_offset;
-
- unpack_dname(p, rr->rr_dname, sizeof(rr->rr_dname));
- unpack_u16(p, &rr->rr_type);
- unpack_u16(p, &rr->rr_class);
- unpack_u32(p, &rr->rr_ttl);
- unpack_u16(p, &rdlen);
-
- if (p->err)
- return (-1);
-
- if (p->len - p->offset < rdlen) {
- p->err = EOVERFLOW;
- return (-1);
- }
-
- save_offset = p->offset;
-
- switch (rr->rr_type) {
-
- case T_CNAME:
- unpack_dname(p, rr->rr.cname.cname, sizeof(rr->rr.cname.cname));
- break;
-
- case T_MX:
- unpack_u16(p, &rr->rr.mx.preference);
- unpack_dname(p, rr->rr.mx.exchange, sizeof(rr->rr.mx.exchange));
- break;
-
- case T_NS:
- unpack_dname(p, rr->rr.ns.nsname, sizeof(rr->rr.ns.nsname));
- break;
-
- case T_PTR:
- unpack_dname(p, rr->rr.ptr.ptrname, sizeof(rr->rr.ptr.ptrname));
- break;
-
- case T_SOA:
- unpack_dname(p, rr->rr.soa.mname, sizeof(rr->rr.soa.mname));
- unpack_dname(p, rr->rr.soa.rname, sizeof(rr->rr.soa.rname));
- unpack_u32(p, &rr->rr.soa.serial);
- unpack_u32(p, &rr->rr.soa.refresh);
- unpack_u32(p, &rr->rr.soa.retry);
- unpack_u32(p, &rr->rr.soa.expire);
- unpack_u32(p, &rr->rr.soa.minimum);
- break;
-
- case T_A:
- if (rr->rr_class != C_IN)
- goto other;
- unpack_inaddr(p, &rr->rr.in_a.addr);
- break;
-
- case T_AAAA:
- if (rr->rr_class != C_IN)
- goto other;
- unpack_in6addr(p, &rr->rr.in_aaaa.addr6);
- break;
- default:
- other:
- rr->rr.other.rdata = p->buf + p->offset;
- rr->rr.other.rdlen = rdlen;
- p->offset += rdlen;
- }
-
- if (p->err)
- return (-1);
-
- /* make sure that the advertised rdlen is really ok */
- if (p->offset - save_offset != rdlen)
- p->err = EINVAL;
-
- return (p->err) ? (-1) : (0);
-}
-
-static int
-pack_data(struct asr_pack *p, const void *data, size_t len)
-{
- if (p->err)
- return (-1);
-
- if (p->len < p->offset + len) {
- p->err = EOVERFLOW;
- return (-1);
- }
-
- memmove(p->buf + p->offset, data, len);
- p->offset += len;
-
- return (0);
-}
-
-static int
-pack_u16(struct asr_pack *p, uint16_t v)
-{
- v = htons(v);
-
- return (pack_data(p, &v, 2));
-}
-
-static int
-pack_dname(struct asr_pack *p, const char *dname)
-{
- /* dname compression would be nice to have here.
- * need additionnal context.
- */
- return (pack_data(p, dname, strlen(dname) + 1));
-}
-
-int
-_asr_pack_header(struct asr_pack *p, const struct asr_dns_header *h)
-{
- struct asr_dns_header c;
-
- c.id = h->id;
- c.flags = htons(h->flags);
- c.qdcount = htons(h->qdcount);
- c.ancount = htons(h->ancount);
- c.nscount = htons(h->nscount);
- c.arcount = htons(h->arcount);
-
- return (pack_data(p, &c, HFIXEDSZ));
-}
-
-int
-_asr_pack_query(struct asr_pack *p, uint16_t type, uint16_t class, const char *dname)
-{
- pack_dname(p, dname);
- pack_u16(p, type);
- pack_u16(p, class);
-
- return (p->err) ? (-1) : (0);
-}
-
-int
-_asr_pack_edns0(struct asr_pack *p, uint16_t pktsz, int dnssec_do)
-{
- pack_dname(p, ""); /* root */
- pack_u16(p, T_OPT); /* OPT */
- pack_u16(p, pktsz); /* UDP payload size */
-
- /* extended RCODE and flags */
- pack_u16(p, 0);
- pack_u16(p, dnssec_do ? DNS_MESSAGEEXTFLAG_DO : 0);
-
- pack_u16(p, 0); /* RDATA len */
-
- return (p->err) ? (-1) : (0);
-}
-
-int
-_asr_sockaddr_from_str(struct sockaddr *sa, int family, const char *str)
-{
- struct in_addr ina;
- struct in6_addr in6a;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
- char *cp, *str2;
- const char *errstr;
-
- switch (family) {
- case PF_UNSPEC:
- if (_asr_sockaddr_from_str(sa, PF_INET, str) == 0)
- return (0);
- return _asr_sockaddr_from_str(sa, PF_INET6, str);
-
- case PF_INET:
- if (inet_pton(PF_INET, str, &ina) != 1)
- return (-1);
-
- sin = (struct sockaddr_in *)sa;
- memset(sin, 0, sizeof *sin);
- sin->sin_len = sizeof(struct sockaddr_in);
- sin->sin_family = PF_INET;
- sin->sin_addr.s_addr = ina.s_addr;
- return (0);
-
- case PF_INET6:
- cp = strchr(str, SCOPE_DELIMITER);
- if (cp) {
- str2 = strdup(str);
- if (str2 == NULL)
- return (-1);
- str2[cp - str] = '\0';
- if (inet_pton(PF_INET6, str2, &in6a) != 1) {
- free(str2);
- return (-1);
- }
- cp++;
- free(str2);
- } else if (inet_pton(PF_INET6, str, &in6a) != 1)
- return (-1);
-
- sin6 = (struct sockaddr_in6 *)sa;
- memset(sin6, 0, sizeof *sin6);
- sin6->sin6_len = sizeof(struct sockaddr_in6);
- sin6->sin6_family = PF_INET6;
- sin6->sin6_addr = in6a;
-
- if (cp == NULL)
- return (0);
-
- if (IN6_IS_ADDR_LINKLOCAL(&in6a) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&in6a) ||
- IN6_IS_ADDR_MC_INTFACELOCAL(&in6a))
- if ((sin6->sin6_scope_id = if_nametoindex(cp)))
- return (0);
-
- sin6->sin6_scope_id = strtonum(cp, 0, UINT32_MAX, &errstr);
- if (errstr)
- return (-1);
- return (0);
-
- default:
- break;
- }
-
- return (-1);
-}
-
-ssize_t
-_asr_addr_as_fqdn(const char *addr, int family, char *dst, size_t max)
-{
- const struct in6_addr *in6_addr;
- in_addr_t in_addr;
-
- switch (family) {
- case AF_INET:
- in_addr = ntohl(*((const in_addr_t *)addr));
- snprintf(dst, max,
- "%d.%d.%d.%d.in-addr.arpa.",
- in_addr & 0xff,
- (in_addr >> 8) & 0xff,
- (in_addr >> 16) & 0xff,
- (in_addr >> 24) & 0xff);
- break;
- case AF_INET6:
- in6_addr = (const struct in6_addr *)addr;
- snprintf(dst, max,
- "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
- "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
- "ip6.arpa.",
- in6_addr->s6_addr[15] & 0xf,
- (in6_addr->s6_addr[15] >> 4) & 0xf,
- in6_addr->s6_addr[14] & 0xf,
- (in6_addr->s6_addr[14] >> 4) & 0xf,
- in6_addr->s6_addr[13] & 0xf,
- (in6_addr->s6_addr[13] >> 4) & 0xf,
- in6_addr->s6_addr[12] & 0xf,
- (in6_addr->s6_addr[12] >> 4) & 0xf,
- in6_addr->s6_addr[11] & 0xf,
- (in6_addr->s6_addr[11] >> 4) & 0xf,
- in6_addr->s6_addr[10] & 0xf,
- (in6_addr->s6_addr[10] >> 4) & 0xf,
- in6_addr->s6_addr[9] & 0xf,
- (in6_addr->s6_addr[9] >> 4) & 0xf,
- in6_addr->s6_addr[8] & 0xf,
- (in6_addr->s6_addr[8] >> 4) & 0xf,
- in6_addr->s6_addr[7] & 0xf,
- (in6_addr->s6_addr[7] >> 4) & 0xf,
- in6_addr->s6_addr[6] & 0xf,
- (in6_addr->s6_addr[6] >> 4) & 0xf,
- in6_addr->s6_addr[5] & 0xf,
- (in6_addr->s6_addr[5] >> 4) & 0xf,
- in6_addr->s6_addr[4] & 0xf,
- (in6_addr->s6_addr[4] >> 4) & 0xf,
- in6_addr->s6_addr[3] & 0xf,
- (in6_addr->s6_addr[3] >> 4) & 0xf,
- in6_addr->s6_addr[2] & 0xf,
- (in6_addr->s6_addr[2] >> 4) & 0xf,
- in6_addr->s6_addr[1] & 0xf,
- (in6_addr->s6_addr[1] >> 4) & 0xf,
- in6_addr->s6_addr[0] & 0xf,
- (in6_addr->s6_addr[0] >> 4) & 0xf);
- break;
- default:
- return (-1);
- }
- return (0);
-}
-
-/* from asr_debug.c */
-static const char *
-rcodetostr(uint16_t v)
-{
- switch (v) {
- case NOERROR: return "NOERROR";
- case FORMERR: return "FORMERR";
- case SERVFAIL: return "SERVFAIL";
- case NXDOMAIN: return "NXDOMAIN";
- case NOTIMP: return "NOTIMP";
- case REFUSED: return "REFUSED";
- default: return "?";
- }
-}
-
-#define OPCODE_SHIFT 11
-
-const char *
-print_header(const struct asr_dns_header *h, char *buf, size_t max)
-{
- snprintf(buf, max,
- "id:0x%04x %s op:%i %s %s %s %s z:%i %s %s r:%s qd:%i an:%i ns:%i ar:%i",
- ((int)h->id),
- (h->flags & QR_MASK) ? "QR":" ",
- (int)(OPCODE(h->flags) >> OPCODE_SHIFT),
- (h->flags & AA_MASK) ? "AA":" ",
- (h->flags & TC_MASK) ? "TC":" ",
- (h->flags & RD_MASK) ? "RD":" ",
- (h->flags & RA_MASK) ? "RA":" ",
- (h->flags & Z_MASK),
- (h->flags & AD_MASK) ? "AD":" ",
- (h->flags & CD_MASK) ? "CD":" ",
- rcodetostr(RCODE(h->flags)),
- h->qdcount, h->ancount, h->nscount, h->arcount);
-
- return (buf);
-}
-
-const char *
-print_query(const struct asr_dns_query *q, char *buf, size_t max)
-{
- char b[256];
-
- snprintf(buf, max, "%s %s %s",
- print_dname(q->q_dname, b, sizeof b),
- __p_class(q->q_class), __p_type(q->q_type));
-
- return (buf);
-}
-
-const char *
-print_dname(const char *_dname, char *buf, size_t max)
-{
- return (_asr_strdname(_dname, buf, max));
-}
-
-#if 0
-/* from asr.c XXX when linking statically we get access to this via libc */
-/*
- * Turn a (uncompressed) DNS domain name into a regular nul-terminated string
- * where labels are separated by dots. The result is put into the "buf" buffer,
- * truncated if it exceeds "max" chars. The function returns "buf".
- */
-char *
-_asr_strdname(const char *_dname, char *buf, size_t max)
-{
- const unsigned char *dname = _dname;
- char *res;
- size_t left, n, count;
-
- if (_dname[0] == 0) {
- strlcpy(buf, ".", max);
- return buf;
- }
-
- res = buf;
- left = max - 1;
- for (n = 0; dname[0] && left; n += dname[0]) {
- count = (dname[0] < (left - 1)) ? dname[0] : (left - 1);
- memmove(buf, dname + 1, count);
- dname += dname[0] + 1;
- left -= count;
- buf += count;
- if (left) {
- left -= 1;
- *buf++ = '.';
- }
- }
- buf[0] = 0;
-
- return (res);
-}
-#endif
diff --git a/sbin/unwind/frontend.c b/sbin/unwind/frontend.c
index d4b0fd7ab03..a1542257b62 100644
--- a/sbin/unwind/frontend.c
+++ b/sbin/unwind/frontend.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: frontend.c,v 1.1 2019/01/23 13:11:00 florian Exp $ */
+/* $OpenBSD: frontend.c,v 1.2 2019/01/24 15:33:44 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -47,7 +47,15 @@
#include <string.h>
#include <unistd.h>
-#include "asr_private.h"
+#include <assert.h>
+#include "libunbound/config.h"
+#include "libunbound/libunbound/unbound.h"
+#include "libunbound/unbound-event.h"
+#include "libunbound/sldns/rrdef.h"
+#include "libunbound/sldns/pkthdr.h"
+#include "libunbound/sldns/sbuffer.h"
+#include "libunbound/sldns/wire2str.h"
+
#include "uw_log.h"
#include "unwind.h"
#include "frontend.h"
@@ -483,41 +491,62 @@ udp_receive(int fd, short events, void *arg)
struct udp_ev *udpev = (struct udp_ev *)arg;
struct pending_query *pq;
struct query_imsg *query_imsg;
- struct asr_unpack p;
- struct asr_dns_header h;
- struct asr_dns_query q;
- ssize_t len;
- char *str_from, buf[1024];
-
+ ssize_t len, rem_len, buf_len;
+ uint16_t qdcount, ancount, nscount, arcount, t, c;
+ uint8_t *queryp;
+ char *str_from, *str, buf[1024], *bufp;
if ((len = recvmsg(fd, &udpev->rcvmhdr, 0)) < 0) {
log_warn("recvmsg");
return;
}
- str_from = ip_port((struct sockaddr *)&udpev->from);
+ bufp = buf;
+ buf_len = sizeof(buf);
- _asr_unpack_init(&p, udpev->query, len);
+ str_from = ip_port((struct sockaddr *)&udpev->from);
- if (_asr_unpack_header(&p, &h) == -1) {
- log_warnx("bad query: %s, from: %s", strerror(p.err), str_from);
+ if (len < LDNS_HEADER_SIZE) {
+ log_warnx("bad query: too short, from: %s", str_from);
return;
}
- if (h.qdcount != 1 && h.ancount != 0 && h.nscount != 0 &&
- h.arcount != 0) {
+ qdcount = LDNS_QDCOUNT(udpev->query);
+ ancount = LDNS_ANCOUNT(udpev->query);
+ nscount = LDNS_NSCOUNT(udpev->query);
+ arcount = LDNS_ARCOUNT(udpev->query);
+
+ if (qdcount != 1 && ancount != 0 && nscount != 0 && arcount != 0) {
log_warnx("invalid query from %s, qdcount: %d, ancount: %d "
- "nscount: %d, arcount: %d", str_from, h.qdcount, h.ancount,
- h.nscount, h.arcount);
+ "nscount: %d, arcount: %d", str_from, qdcount, ancount,
+ nscount, arcount);
return;
}
log_debug("query from %s", str_from);
- log_debug(";; HEADER %s", print_header(&h, buf, sizeof(buf)));
- log_debug(";; QUERY SECTION:");
- if (_asr_unpack_query(&p, &q) == -1)
- goto error;
- log_debug("%s", print_query(&q, buf, sizeof(buf)));
+ if ((str = sldns_wire2str_pkt(udpev->query, len)) != NULL) {
+ log_debug("%s", str);
+ free(str);
+ }
+
+ queryp = udpev->query;
+ rem_len = len;
+
+ queryp += LDNS_HEADER_SIZE;
+ rem_len -= LDNS_HEADER_SIZE;
+
+ sldns_wire2str_dname_scan(&queryp, &rem_len, &bufp, &buf_len,
+ udpev->query, len);
+
+ if (rem_len < 4) {
+ log_warnx("malformed query");
+ return;
+ }
+
+ t = sldns_read_uint16(queryp);
+ c = sldns_read_uint16(queryp+2);
+ queryp += 4;
+ rem_len -= 4;
if ((pq = malloc(sizeof(*pq))) == NULL) {
log_warn(NULL);
@@ -544,11 +573,18 @@ udp_receive(int fd, short events, void *arg)
return;
}
- /* XXX */
- print_dname(q.q_dname, query_imsg->qname, sizeof(query_imsg->qname));
+ if (strlcpy(query_imsg->qname, buf, sizeof(query_imsg->qname)) >=
+ sizeof(buf)) {
+ log_warnx("qname too long");
+ free(query_imsg);
+ /* XXX SERVFAIL */
+ free(pq->query);
+ free(pq);
+ return;
+ }
query_imsg->id = pq->imsg_id;
- query_imsg->t = q.q_type;
- query_imsg->c = q.q_class;
+ query_imsg->t = t;
+ query_imsg->c = c;
if (frontend_imsg_compose_resolver(IMSG_QUERY, 0, query_imsg,
sizeof(*query_imsg)) != -1) {
@@ -560,62 +596,39 @@ udp_receive(int fd, short events, void *arg)
free(pq);
}
-error:
- if (p.err)
- log_debug(";; ERROR AT OFFSET %zu/%zu: %s", p.offset, p.len,
- strerror(p.err));
}
void
send_answer(struct pending_query *pq, uint8_t *answer, ssize_t len)
{
- struct asr_pack p;
- struct asr_unpack query_u, answer_u;
- struct asr_dns_header query_h, answer_h;
-
log_debug("result for %s",
ip_port((struct sockaddr*)&pq->from));
- _asr_unpack_init(&query_u, pq->query, pq->len);
- _asr_unpack_header(&query_u, &query_h); /* XXX */
-
if (answer == NULL) {
answer = pq->query;
len = pq->len;
- _asr_unpack_init(&answer_u, answer, len);
- _asr_unpack_header(&answer_u, &answer_h); /* XXX */
- answer_h.flags = 0;
- answer_h.flags |= RA_MASK;
- answer_h.flags = (answer_h.flags & ~RCODE_MASK) | SERVFAIL;
+ LDNS_QR_SET(answer);
+ LDNS_RA_SET(answer);
+ LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL);
} else {
- _asr_unpack_init(&answer_u, answer, len);
- _asr_unpack_header(&answer_u, &answer_h); /* XXX */
-
if (pq->bogus) {
- if(query_h.flags & CD_MASK) {
- answer_h.id = query_h.id;
- answer_h.flags |= CD_MASK;
+ if(LDNS_CD_WIRE(pq->query)) {
+ LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query));
+ LDNS_CD_SET(answer);
} else {
answer = pq->query;
len = pq->len;
- _asr_unpack_init(&answer_u, answer, len);
- _asr_unpack_header(&answer_u, &answer_h); /* XXX */
-
- answer_h.flags = 0;
- answer_h.flags |= RA_MASK;
- answer_h.flags = (answer_h.flags & ~RCODE_MASK)
- | SERVFAIL;
+ LDNS_QR_SET(answer);
+ LDNS_RA_SET(answer);
+ LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL);
}
} else {
- answer_h.id = query_h.id;
+ LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query));
}
}
- _asr_pack_init(&p, answer, len);
- _asr_pack_header(&p, &answer_h);
-
if(sendto(pq->fd, answer, len, 0, (struct sockaddr *)
&pq->from, pq->from.ss_len) == -1)
log_warn("sendto");
diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c
index d8b742c205a..708d5485f4a 100644
--- a/sbin/unwind/resolver.c
+++ b/sbin/unwind/resolver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolver.c,v 1.2 2019/01/24 15:32:08 florian Exp $ */
+/* $OpenBSD: resolver.c,v 1.3 2019/01/24 15:33:44 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -28,7 +28,6 @@
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
-#include <arpa/nameser.h>
#include <errno.h>
#include <event.h>
@@ -43,17 +42,22 @@
#include <time.h>
#include <unistd.h>
-#include <unbound.h>
-#include <unbound-event.h>
+#include <assert.h>
+#include "libunbound/config.h"
+#include "libunbound/libunbound/unbound.h"
+#include "libunbound/unbound-event.h"
+#include "libunbound/sldns/rrdef.h"
+#include "libunbound/sldns/pkthdr.h"
+#include "libunbound/sldns/sbuffer.h"
+#include "libunbound/sldns/wire2str.h"
#include <openssl/crypto.h>
-#include "asr_private.h"
#include "uw_log.h"
#include "unwind.h"
#include "resolver.h"
-#define CHROOT_DIR "/etc/unwind"
+#define CHROOT "/etc/unwind"
#define DB_DIR "/trustanchor/"
#define ROOT_KEY DB_DIR"root.key"
@@ -163,7 +167,7 @@ resolver(int debug, int verbose)
if ((pw = getpwnam(UNWIND_USER)) == NULL)
fatal("getpwnam");
- if (chroot(CHROOT_DIR) == -1)
+ if (chroot(CHROOT) == -1)
fatal("chroot");
if (chdir("/") == -1)
fatal("chdir(\"/\")");
@@ -474,11 +478,10 @@ resolve_done(void *arg, int rcode, void *answer_packet, int answer_len,
{
struct query_imsg *query_imsg;
struct unwind_resolver *res;
- struct asr_unpack p;
- struct asr_dns_header h;
struct timespec tp, elapsed;
int64_t ms;
size_t i;
+ char *str;
clock_gettime(CLOCK_MONOTONIC, &tp);
@@ -504,19 +507,22 @@ resolve_done(void *arg, int rcode, void *answer_packet, int answer_len,
log_debug("%s: rcode: %d", __func__, rcode);
- _asr_unpack_init(&p, answer_packet, answer_len);
-
- if (_asr_unpack_header(&p, &h) == -1) {
- log_warnx("bad packet: %s", strerror(p.err));
+ if (answer_len < LDNS_HEADER_SIZE) {
+ log_warnx("bad packet: too short");
goto servfail;
}
- if (rcode == SERVFAIL) {
+ if (rcode == LDNS_RCODE_SERVFAIL) {
if (res->stop != 1)
check_resolver(res);
goto servfail;
}
+ if ((str = sldns_wire2str_pkt(answer_packet, answer_len)) != NULL) {
+ log_debug("%s", str);
+ free(str);
+ }
+
query_imsg->err = 0;
if (res->state == VALIDATING)
@@ -748,7 +754,8 @@ check_resolver(struct unwind_resolver *res)
data->check_res = check_res;
data->res = res;
- if ((err = ub_resolve_event(check_res->ctx, ".", T_NS, C_IN, data,
+ if ((err = ub_resolve_event(check_res->ctx, ".", LDNS_RR_TYPE_NS,
+ LDNS_RR_CLASS_IN, data,
check_resolver_done, NULL)) != 0) {
log_warn("%s: ub_resolve_event: err: %d, %s",
__func__, err, ub_strerror(err));
@@ -763,26 +770,28 @@ check_resolver_done(void *arg, int rcode, void *answer_packet, int answer_len,
int sec, char *why_bogus, int was_ratelimited)
{
struct check_resolver_data *data;
- struct asr_unpack p;
- struct asr_dns_header h;
+ char *str;
data = (struct check_resolver_data *)arg;
log_debug("%s: rcode: %d", __func__, rcode);
- _asr_unpack_init(&p, answer_packet, answer_len);
-
- if (_asr_unpack_header(&p, &h) == -1) {
+ if (answer_len < LDNS_HEADER_SIZE) {
data->res->state = DEAD;
- log_warnx("bad packet: %s", strerror(p.err));
+ log_warnx("bad packet: too short");
goto out;
}
- if (rcode == SERVFAIL) {
+ if (rcode == LDNS_RCODE_SERVFAIL) {
data->res->state = DEAD;
goto out;
}
+ if ((str = sldns_wire2str_pkt(answer_packet, answer_len)) != NULL) {
+ log_debug("%s", str);
+ free(str);
+ }
+
if (sec == 2)
data->res->state = VALIDATING;
else if (rcode == 0) {