From 2b1c6979bb36a0e3a5aaa7f18b0c72b528f886b9 Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 2 Mar 2000 01:34:04 +0000 Subject: [PATCH] + * New adns_submit_reverse_any for eg RBL lookups, and corresponding @@ -1,11 +1,14 @@ adns (0.7) BETA; urgency=medium + * New adns_submit_reverse_any for eg RBL lookups, and corresponding + option to adnshost. * README updated (from www home page). - * Better reporting of unexpected or weird replies from nameserver. + + * In answers, quote all except alphanums and - _ / + (and document). + * Don't reject specials in cnames even without adns_qf_quotefail_cname. * Better checking of long domain names and labels in queries. - * Unfortunately, answer->owner may be null on error. Documented. - * In answers, quote everything except alphanums and - _ / + and document - this behaviour. Make not setting adns_qf_quotefail_cname work. + * answer->owner may be null on error. Documented, and adnshost copes. + * Better reporting of unexpected or weird replies from nameserver. -- --- changelog | 11 +++++--- client/adh-main.c | 17 ++++++++++--- client/adh-opts.c | 20 ++++++++++++--- client/adh-query.c | 29 +++++++++++++++++++--- client/adnshost.h | 13 ++++------ regress/case-ptrbaddom.err | 0 regress/case-ptrbaddom.out | 7 ++++++ regress/case-ptrbaddom.sys | 51 ++++++++++++++++++++++++++++++++++++++ src/adns.h | 13 ++++++++++ src/query.c | 44 ++++++++++++++++++++++++-------- 10 files changed, 171 insertions(+), 34 deletions(-) create mode 100644 regress/case-ptrbaddom.err create mode 100644 regress/case-ptrbaddom.out create mode 100644 regress/case-ptrbaddom.sys diff --git a/changelog b/changelog index 3989b51..942f20b 100644 --- a/changelog +++ b/changelog @@ -1,11 +1,14 @@ adns (0.7) BETA; urgency=medium + * New adns_submit_reverse_any for eg RBL lookups, and corresponding + option to adnshost. * README updated (from www home page). - * Better reporting of unexpected or weird replies from nameserver. + + * In answers, quote all except alphanums and - _ / + (and document). + * Don't reject specials in cnames even without adns_qf_quotefail_cname. * Better checking of long domain names and labels in queries. - * Unfortunately, answer->owner may be null on error. Documented. - * In answers, quote everything except alphanums and - _ / + and document - this behaviour. Make not setting adns_qf_quotefail_cname work. + * answer->owner may be null on error. Documented, and adnshost copes. + * Better reporting of unexpected or weird replies from nameserver. -- diff --git a/client/adh-main.c b/client/adh-main.c index 81cff54..3fa1adb 100644 --- a/client/adh-main.c +++ b/client/adh-main.c @@ -62,7 +62,7 @@ char *xstrsave(const char *str) { return p; } -void of_type(const struct optioninfo *oi, const char *arg) { +void of_type(const struct optioninfo *oi, const char *arg, const char *arg2) { static const struct typename { adns_rrtype type; const char *desc; @@ -106,6 +106,7 @@ static void process_optarg(const char *arg, const char *const **argv_p, const char *value) { const struct optioninfo *oip; + const char *arg2; int invert; if (arg[0] == '-' || arg[0] == '+') { @@ -120,11 +121,19 @@ static void process_optarg(const char *arg, if (oip->type == ot_funcarg) { arg= argv_p ? *++(*argv_p) : value; if (!arg) usageerr("option --%s requires a value argument",oip->lopt); + arg2= 0; + } else if (oip->type == ot_funcarg2) { + assert(argv_p); + arg= *++(*argv_p); + if (arg) arg2= *++(*argv_p); + if (!arg || !arg2) + usageerr("option --%s requires two more arguments", oip->lopt); } else { if (value) usageerr("option --%s does not take a value",oip->lopt); arg= 0; + arg2= 0; } - opt_do(oip,arg,invert); + opt_do(oip,invert,arg,arg2); } else if (arg[0] == '-' && arg[1] == 0) { arg= argv_p ? *++(*argv_p) : value; if (!arg) usageerr("option `-' must be followed by a domain"); @@ -141,11 +150,11 @@ static void process_optarg(const char *arg, } else { if (value) usageerr("two values for option -%s given !",oip->sopt); } - opt_do(oip,arg,invert); + opt_do(oip,invert,arg,0); arg= ""; } else { if (value) usageerr("option -%s does not take a value",oip->sopt); - opt_do(oip,0,invert); + opt_do(oip,invert,0,0); } } } diff --git a/client/adh-opts.c b/client/adh-opts.c index 46d5606..af8afbd 100644 --- a/client/adh-opts.c +++ b/client/adh-opts.c @@ -74,6 +74,8 @@ static const struct optioninfo perquery_options[]= { "t", "type", 0,0, &of_type, "type" }, { ot_funcarg, "Do reverse query (address -> name lookup)", "i", "ptr", 0,0, &of_ptr, "addr" }, + { ot_funcarg2, "Lookup in in-addr-like `zone' (eg MAPS RBL)", + 0, "reverse", 0,0, &of_reverse, "addr","zone" }, { ot_desconly, "per-query binary options:" }, { ot_flag, "Use the search list", @@ -192,6 +194,15 @@ static void printusage(void) { oip->desc); } break; + case ot_funcarg2: + assert(!oip->sopt); + l= (maxlopt + maxsopt - 2 - + (strlen(oip->lopt) + strlen(oip->argdesc) + strlen(oip->argdesc2))); + printf(" --%s <%s> <%s>%*s%s\n", + oip->lopt, oip->argdesc, oip->argdesc2, + l>2 ? l : 2, "", + oip->desc); + break; case ot_desconly: printf("%s\n", oip->desc); break; @@ -256,7 +267,7 @@ static void printusage(void) { if (ferror(stdout)) sysfail("write usage message",errno); } -void of_help(const struct optioninfo *oi, const char *arg) { +void of_help(const struct optioninfo *oi, const char *arg, const char *arg2) { printusage(); if (fclose(stdout)) sysfail("finish writing output",errno); exit(0); @@ -316,7 +327,8 @@ static void noninvert(const struct optioninfo *oip) { oip->lopt ? "--" : "", oip->lopt ? oip->lopt : ""); } -void opt_do(const struct optioninfo *oip, const char *arg, int invert) { +void opt_do(const struct optioninfo *oip, int invert, + const char *arg, const char *arg2) { switch (oip->type) { case ot_flag: assert(!arg); @@ -327,9 +339,9 @@ void opt_do(const struct optioninfo *oip, const char *arg, int invert) { if (invert) noninvert(oip); *oip->storep= oip->value; return; - case ot_func: case ot_funcarg: + case ot_func: case ot_funcarg: case ot_funcarg2: if (invert) noninvert(oip); - oip->func(oip,arg); + oip->func(oip,arg,arg2); return; default: abort(); diff --git a/client/adh-query.c b/client/adh-query.c index cc5dc12..a25c894 100644 --- a/client/adh-query.c +++ b/client/adh-query.c @@ -79,7 +79,7 @@ static void prep_query(struct query_node **qun_r, int *quflags_r) { *qun_r= qun; } -void of_ptr(const struct optioninfo *oi, const char *arg) { +void of_ptr(const struct optioninfo *oi, const char *arg, const char *arg2) { struct query_node *qun; int quflags, r; struct sockaddr_in sa; @@ -101,6 +101,29 @@ void of_ptr(const struct optioninfo *oi, const char *arg) { LIST_LINK_TAIL(outstanding,qun); } +void of_reverse(const struct optioninfo *oi, const char *arg, const char *arg2) { + struct query_node *qun; + int quflags, r; + struct sockaddr_in sa; + + memset(&sa,0,sizeof(sa)); + sa.sin_family= AF_INET; + if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg); + + prep_query(&qun,&quflags); + qun->owner= xmalloc(strlen(arg) + strlen(arg2) + 2); + sprintf(qun->owner, "%s %s", arg,arg2); + r= adns_submit_reverse_any(ads, + (struct sockaddr*)&sa, arg2, + ov_type == adns_r_none ? adns_r_txt : ov_type, + quflags, + qun, + &qun->qu); + if (r) sysfail("adns_submit_reverse",r); + + LIST_LINK_TAIL(outstanding,qun); +} + void query_do(const char *domain) { struct query_node *qun; int quflags, r; @@ -263,12 +286,12 @@ void query_done(struct query_node *qun, adns_answer *answer) { dequeue_query(qun); } -void of_asynch_id(const struct optioninfo *oi, const char *arg) { +void of_asynch_id(const struct optioninfo *oi, const char *arg, const char *arg2) { free(ov_id); ov_id= xstrsave(arg); } -void of_cancel_id(const struct optioninfo *oi, const char *arg) { +void of_cancel_id(const struct optioninfo *oi, const char *arg, const char *arg2) { struct query_node *qun; for (qun= outstanding.head; diff --git a/client/adnshost.h b/client/adnshost.h index 93a7608..1918047 100644 --- a/client/adnshost.h +++ b/client/adnshost.h @@ -49,18 +49,18 @@ /* declarations related to option processing */ struct optioninfo; -typedef void optfunc(const struct optioninfo *oi, const char *arg); +typedef void optfunc(const struct optioninfo *oi, const char *arg, const char *arg2); struct optioninfo { enum oi_type { ot_end, ot_desconly, - ot_flag, ot_value, ot_func, ot_funcarg + ot_flag, ot_value, ot_func, ot_funcarg, ot_funcarg2 } type; const char *desc; const char *sopt, *lopt; int *storep, value; optfunc *func; - const char *argdesc; + const char *argdesc, *argdesc2; }; enum ttlmode { tm_none, tm_rel, tm_abs }; @@ -79,11 +79,11 @@ extern int ov_tcp, ov_cname, ov_format; extern char *ov_id; extern struct perqueryflags_remember ov_pqfr; -extern optfunc of_help, of_type, of_ptr, of_asynch_id, of_cancel_id; +extern optfunc of_help, of_type, of_ptr, of_reverse, of_asynch_id, of_cancel_id; const struct optioninfo *opt_findl(const char *opt); const struct optioninfo *opt_finds(const char **optp); -void opt_do(const struct optioninfo *oip, const char *arg, int invert); +void opt_do(const struct optioninfo *oip, int invert, const char *arg, const char *arg2); /* declarations related to query processing */ @@ -101,9 +101,6 @@ void ensure_adns_init(void); void query_do(const char *domain); void query_done(struct query_node *qun, adns_answer *answer); -void of_asynch_id(const struct optioninfo *oi, const char *arg); -void of_cancel_id(const struct optioninfo *oi, const char *arg); - /* declarations related to main program and useful utility functions */ void sysfail(const char *what, int errnoval) NONRETURNING; diff --git a/regress/case-ptrbaddom.err b/regress/case-ptrbaddom.err new file mode 100644 index 0000000..e69de29 diff --git a/regress/case-ptrbaddom.out b/regress/case-ptrbaddom.out new file mode 100644 index 0000000..3be9371 --- /dev/null +++ b/regress/case-ptrbaddom.out @@ -0,0 +1,7 @@ +adns debug: using nameserver 172.18.45.6 +37.45.18.172.in-addr.arpa.test.iwj.relativity.greenend.org.uk. flags 0 type 12 PTR(raw) submitted +37.45.18.172.in-addr.arpa.test.iwj.relativity.greenend.org.uk. flags 0 type 65548 PTR(checked) submitted +37.45.18.172.in-addr.arpa.test.iwj.relativity.greenend.org.uk. flags 0 type PTR(raw): OK; nrrs=1; cname=$; owner=$; ttl=60 + ptr.test.iwj.relativity.greenend.org.uk +37.45.18.172.in-addr.arpa.test.iwj.relativity.greenend.org.uk. flags 0 type PTR(checked): Domain invalid for particular DNS query type; nrrs=0; cname=$; owner=$; ttl=60 +rc=0 diff --git a/regress/case-ptrbaddom.sys b/regress/case-ptrbaddom.sys new file mode 100644 index 0000000..6b12372 --- /dev/null +++ b/regress/case-ptrbaddom.sys @@ -0,0 +1,51 @@ +default +:12,65548 37.45.18.172.in-addr.arpa.test.iwj.relativity.greenend.org.uk. + start 951960654.608219 + socket type=SOCK_DGRAM + socket=4 + +0.000194 + fcntl fd=4 cmd=F_GETFL + fcntl=~O_NONBLOCK&... + +0.000055 + fcntl fd=4 cmd=F_SETFL O_NONBLOCK|... + fcntl=OK + +0.000035 + sendto fd=4 addr=172.18.45.6:53 + 311f0100 00010000 00000000 02333702 34350231 38033137 3207696e 2d616464 + 72046172 70610474 65737403 69776a0a 72656c61 74697669 74790867 7265656e + 656e6403 6f726702 756b0000 0c0001. + sendto=79 + +0.001355 + sendto fd=4 addr=172.18.45.6:53 + 31200100 00010000 00000000 02333702 34350231 38033137 3207696e 2d616464 + 72046172 70610474 65737403 69776a0a 72656c61 74697669 74790867 7265656e + 656e6403 6f726702 756b0000 0c0001. + sendto=79 + +0.000776 + select max=5 rfds=[4] wfds=[] efds=[] to=1.997869 + select=1 rfds=[4] wfds=[] efds=[] + +0.000258 + recvfrom fd=4 buflen=512 *addrlen=16 + recvfrom=OK addr=172.18.45.6:53 + 311f8580 00010001 00010001 02333702 34350231 38033137 3207696e 2d616464 + 72046172 70610474 65737403 69776a0a 72656c61 74697669 74790867 7265656e + 656e6403 6f726702 756b0000 0c0001c0 0c000c00 01000000 3c002903 70747204 + 74657374 0369776a 0a72656c 61746976 69747908 67726565 6e656e64 036f7267 + 02756b00 c05f0002 00010000 003c0006 036e7330 c068c090 00010001 00015180 + 0004ac12 2d06. + +0.000613 + recvfrom fd=4 buflen=512 *addrlen=16 + recvfrom=OK addr=172.18.45.6:53 + 31208580 00010001 00010001 02333702 34350231 38033137 3207696e 2d616464 + 72046172 70610474 65737403 69776a0a 72656c61 74697669 74790867 7265656e + 656e6403 6f726702 756b0000 0c0001c0 0c000c00 01000000 3c002903 70747204 + 74657374 0369776a 0a72656c 61746976 69747908 67726565 6e656e64 036f7267 + 02756b00 c05f0002 00010000 003c0006 036e7330 c068c090 00010001 00015180 + 0004ac12 2d06. + +0.000711 + recvfrom fd=4 buflen=512 *addrlen=16 + recvfrom=EAGAIN + +0.000133 + close fd=4 + close=OK + +0.000187 diff --git a/src/adns.h b/src/adns.h index a1e0877..6c07e64 100644 --- a/src/adns.h +++ b/src/adns.h @@ -511,6 +511,19 @@ int adns_submit_reverse(adns_state ads, * addr->sa_family must be AF_INET or you get ENOSYS. */ +int adns_submit_reverse_any(adns_state ads, + const struct sockaddr *addr, + const char *rzone, + adns_rrtype type, + adns_queryflags flags, + void *context, + adns_query *query_r); +/* For RBL-style reverse `zone's; look up + * . + * Any type is allowed. _qf_search is ignored. + * addr->sa_family must be AF_INET or you get ENOSYS. + */ + void adns_finish(adns_state ads); /* You may call this even if you have queries outstanding; * they will be cancelled. diff --git a/src/query.c b/src/query.c index 5e345ae..a8423d7 100644 --- a/src/query.c +++ b/src/query.c @@ -267,25 +267,47 @@ int adns_submit(adns_state ads, return r; } -int adns_submit_reverse(adns_state ads, - const struct sockaddr *addr, - adns_rrtype type, - adns_queryflags flags, - void *context, - adns_query *query_r) { +int adns_submit_reverse_any(adns_state ads, + const struct sockaddr *addr, + const char *zone, + adns_rrtype type, + adns_queryflags flags, + void *context, + adns_query *query_r) { const unsigned char *iaddr; - char buf[30]; + char *buf, *buf_free; + char shortbuf[100]; + int r, lreq; - if (type != adns_r_ptr && type != adns_r_ptr_raw) return EINVAL; flags &= ~adns_qf_search; if (addr->sa_family != AF_INET) return ENOSYS; iaddr= (const unsigned char*) &(((const struct sockaddr_in*)addr) -> sin_addr); - sprintf(buf, "%d.%d.%d.%d.in-addr.arpa", - iaddr[3], iaddr[2], iaddr[1], iaddr[0]); + lreq= strlen(zone) + 4*4 + 1; + if (lreq > sizeof(shortbuf)) { + buf= malloc(strlen(zone) + 4*4 + 1); + if (!buf) return errno; + buf_free= buf; + } else { + buf= shortbuf; + buf_free= 0; + } + sprintf(buf, "%d.%d.%d.%d.%s", iaddr[3], iaddr[2], iaddr[1], iaddr[0], zone); - return adns_submit(ads,buf,type,flags,context,query_r); + r= adns_submit(ads,buf,type,flags,context,query_r); + free(buf_free); + return r; +} + +int adns_submit_reverse(adns_state ads, + const struct sockaddr *addr, + adns_rrtype type, + adns_queryflags flags, + void *context, + adns_query *query_r) { + if (type != adns_r_ptr && type != adns_r_ptr_raw) return EINVAL; + return adns_submit_reverse_any(ads,addr,"in-addr.arpa",type,flags,context,query_r); } int adns_synchronous(adns_state ads, -- 2.30.2