From a6536d8becc65c37fbeab7bc0793c6dd55bea977 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 15 Nov 1998 22:36:52 +0000 Subject: [PATCH] Do PTR checking (multiple PTRs allowed). --- client/adnstest.c | 5 ++- src/event.c | 2 +- src/general.c | 2 +- src/internal.h | 24 +++++----- src/query.c | 9 ++-- src/types.c | 110 +++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 128 insertions(+), 24 deletions(-) diff --git a/client/adnstest.c b/client/adnstest.c index b4c125a..d8003dc 100644 --- a/client/adnstest.c +++ b/client/adnstest.c @@ -45,6 +45,7 @@ static const adns_rrtype defaulttypes[]= { adns_r_addr, adns_r_ns, adns_r_mx, + adns_r_ptr, adns_r_none }; @@ -73,8 +74,8 @@ int main(int argc, char *const *argv) { for (cp= argv[1]+1, ti=0; ti,...] [ ...]",stderr); + if (ch != ',') { + fputs("usage: dtest [:,...] [ ...]\n",stderr); exit(4); } cp++; diff --git a/src/event.c b/src/event.c index 8f3fb4c..d42afbd 100644 --- a/src/event.c +++ b/src/event.c @@ -374,7 +374,7 @@ static int internal_check(adns_state ads, } LIST_UNLINK(ads->output,qu); *answer= qu->answer; - if (context_r) *context_r= qu->context.ext; + if (context_r) *context_r= qu->ctx.ext; free(qu); return 0; } diff --git a/src/general.c b/src/general.c index 211b6d2..eb03214 100644 --- a/src/general.c +++ b/src/general.c @@ -217,7 +217,7 @@ static const struct sinfo { SINFO( invalidanswerdomain, "Received syntactically invalid domain" ), SINFO( nxdomain, "No such domain" ), SINFO( nodata, "No such data" ), - SINFO( invalidquerydomain, "Domain syntactically invalid" ), + SINFO( invalidquerydomain, "Query domain invalid" ), SINFO( domaintoolong, "Domain name too long" ) }; diff --git a/src/internal.h b/src/internal.h index 33086f6..672e3a9 100644 --- a/src/internal.h +++ b/src/internal.h @@ -50,6 +50,8 @@ typedef unsigned char byte; #define DNS_HDRSIZE 12 #define DNS_CLASS_IN 1 +#define DNS_INADDR_ARPA "in-addr", "arpa" + typedef enum { rcode_noerror, rcode_formaterror, @@ -75,16 +77,6 @@ typedef struct { byte *buf; } vbuf; -typedef union { - void *ext; - struct { - void (*callback)(adns_query parent, adns_query child); - union { - adns_rr_hostaddr *hostaddr; - } info; - } intern; -} qcontext; - typedef struct { adns_state ads; adns_query qu; @@ -142,6 +134,15 @@ union maxalign { union maxalign *up; } data; +typedef struct { + void *ext; + void (*callback)(adns_query parent, adns_query child); + union { + adns_rr_addr ptr_parent_addr; + adns_rr_hostaddr *hostaddr; + } info; +} qcontext; + struct adns__query { adns_state ads; enum { query_udp, query_tcpwait, query_tcpsent, query_child, query_done } state; @@ -179,7 +180,8 @@ struct adns__query { int udpnextserver; unsigned long udpsent, tcpfailed; /* bitmap indexed by server */ struct timeval timeout; - qcontext context; + + qcontext ctx; /* Possible states: * diff --git a/src/query.c b/src/query.c index 7c15a5b..e90d45c 100644 --- a/src/query.c +++ b/src/query.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -62,7 +63,7 @@ int adns__internal_submit(adns_state ads, adns_query *query_r, qu->udpnextserver= 0; qu->udpsent= qu->tcpfailed= 0; timerclear(&qu->timeout); - memcpy(&qu->context,ctx,sizeof(qu->context)); + memcpy(&qu->ctx,ctx,sizeof(qu->ctx)); qu->answer->status= adns_s_ok; qu->answer->cname= 0; @@ -120,6 +121,9 @@ int adns_submit(adns_state ads, if (!typei) return adns_s_notimplemented; ctx.ext= context; + ctx.callback= 0; + memset(&ctx.info,0,sizeof(ctx.info)); + r= gettimeofday(&now,0); if (r) return errno; id= 0; @@ -296,10 +300,9 @@ void adns__query_done(adns_query qu) { parent= qu->parent; if (parent) { LIST_UNLINK_PART(parent->children,qu,siblings.); - qu->context.intern.callback(parent,qu); + qu->ctx.callback(parent,qu); free_query_allocs(qu); free(qu); - if (!parent->children.head) adns__query_done(parent); } else { makefinal_query(qu); LIST_LINK_TAIL(qu->ads->output,qu); diff --git a/src/types.c b/src/types.c index 0050b77..dc91fb0 100644 --- a/src/types.c +++ b/src/types.c @@ -46,6 +46,7 @@ * _mx_raw (pa,di) * _mx (pa,di) * _inthostaddr (mf,cs) + * _ptr (pa) * _flat (mf) * * within each section: @@ -235,7 +236,6 @@ static adns_status pa_addr(const parseinfo *pai, int cbyte, int max, void *datap storeto->len= sizeof(storeto->addr.inet); memset(&storeto->addr,0,sizeof(storeto->addr.inet)); storeto->addr.inet.sin_family= AF_INET; - storeto->addr.inet.sin_port= 0; memcpy(&storeto->addr.inet.sin_addr,dgram+cbyte,4); return adns_s_ok; } @@ -351,13 +351,15 @@ static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha, } static void icb_hostaddr(adns_query parent, adns_query child) { - adns_rr_hostaddr *rrp= child->context.intern.info.hostaddr; adns_answer *cans= child->answer; + adns_rr_hostaddr *rrp= child->ctx.info.hostaddr; rrp->astatus= cans->status; rrp->naddrs= cans->nrrs; rrp->addrs= cans->rrs.addr; adns__transfer_interim(child, parent, rrp->addrs, rrp->naddrs*sizeof(adns_rr_addr)); + + if (!parent->children.head) adns__query_done(parent); } static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io, @@ -393,8 +395,9 @@ static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io, adns_r_addr, adns_qf_quoteok_query); if (st) return st; - ctx.intern.callback= icb_hostaddr; - ctx.intern.info.hostaddr= rrp; + ctx.ext= 0; + ctx.callback= icb_hostaddr; + ctx.info.hostaddr= rrp; st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr), &pai->qu->vb, id, adns_qf_quoteok_query, pai->now, 0, &ctx); @@ -550,6 +553,103 @@ static adns_status cs_inthostaddr(vbuf *vb, const void *datap) { return csp_hostaddr(vb,&rrp->ha); } +/* + * _ptr (pa, +icb_ptr) + */ + +static void icb_ptr(adns_query parent, adns_query child) { + adns_answer *cans= child->answer; + const adns_rr_addr *queried, *found; + int i; + + if (cans->status == adns_s_nxdomain || cans->status == adns_s_nodata) { + adns__query_fail(parent,adns_s_inconsistent); + return; + } else if (cans->status) { + adns__query_fail(parent,cans->status); + return; + } + + queried= &parent->ctx.info.ptr_parent_addr; + for (i=0, found=cans->rrs.addr; inrrs; i++, found++) { + if (queried->len == found->len && + !memcmp(&queried->addr,&found->addr,queried->len)) { + if (!parent->children.head) adns__query_done(parent); + return; + } + } + + adns__query_fail(parent,adns_s_inconsistent); +} + +static adns_status pa_ptr(const parseinfo *pai, int dmstart, int max, void *datap) { + static const char *(expectdomain[])= { DNS_INADDR_ARPA }; + + char **rrp= datap; + adns_status st; + adns_rr_addr *ap; + findlabel_state fls; + char *ep; + byte ipv[4]; + char labbuf[4]; + int cbyte, i, lablen, labstart, l, id; + adns_query nqu; + qcontext ctx; + + cbyte= dmstart; + st= pap_domain(pai, &cbyte, max, rrp, + pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); + if (st) return st; + if (cbyte != max) return adns_s_invaliddata; + + ap= &pai->qu->ctx.info.ptr_parent_addr; + if (!ap->len) { + adns__findlabel_start(&fls, pai->ads, -1, pai->qu, + pai->qu->query_dgram, pai->qu->query_dglen, + pai->qu->query_dglen, DNS_HDRSIZE, 0); + for (i=0; i<4; i++) { + st= adns__findlabel_next(&fls,&lablen,&labstart); assert(!st); + if (lablen<=0 || lablen>3) return adns_s_invalidquerydomain; + memcpy(labbuf, pai->qu->query_dgram + labstart, lablen); labbuf[lablen]= 0; + ipv[3-i]= strtoul(labbuf,&ep,10); if (*ep) return adns_s_invalidquerydomain; + if (lablen>1 && pai->qu->query_dgram[labstart]=='0') + return adns_s_invalidquerydomain; + } + for (i=0; iqu->query_dgram + labstart, expectdomain[i], l)) + return adns_s_invalidquerydomain; + } + st= adns__findlabel_next(&fls,&lablen,0); assert(!st); + if (lablen) return adns_s_invalidquerydomain; + + ap->len= sizeof(struct sockaddr_in); + memset(&ap->addr,0,sizeof(ap->addr.inet)); + ap->addr.inet.sin_family= AF_INET; + ap->addr.inet.sin_addr.s_addr= + htonl((ipv[0]<<24) | (ipv[1]<<16) | (ipv[2]<<8) | (ipv[3])); + } + + st= adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id, + pai->dgram, pai->dglen, dmstart, + adns_r_addr, adns_qf_quoteok_query); + if (st) return st; + + ctx.ext= 0; + ctx.callback= icb_ptr; + memset(&ctx.info,0,sizeof(ctx.info)); + st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr), + &pai->qu->vb, id, + adns_qf_quoteok_query, pai->now, 0, &ctx); + if (st) return st; + + nqu->parent= pai->qu; + LIST_LINK_TAIL_PART(pai->qu->children,nqu,siblings.); + + return adns_s_ok; +} + /* * _flat (mf) */ @@ -592,9 +692,7 @@ static const typeinfo typeinfos[] = { FLAT_TYPE(addr, "A", "addr", addr, pa_addr, di_addr ), DEEP_TYPE(ns, "NS", "+addr", hostaddr, pa_hostaddr, di_hostaddr ), -#if 0 DEEP_TYPE(ptr, "PTR","checked", str, pa_ptr, 0 ), -#endif DEEP_TYPE(mx, "MX", "+addr", inthostaddr, pa_mx, di_mx ), #if 0 -- 2.30.2