chiark / gitweb /
+ * New adns_submit_reverse_any for eg RBL lookups, and corresponding
authorian <ian>
Thu, 2 Mar 2000 01:34:04 +0000 (01:34 +0000)
committerian <ian>
Thu, 2 Mar 2000 01:34:04 +0000 (01:34 +0000)
@@ -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
client/adh-main.c
client/adh-opts.c
client/adh-query.c
client/adnshost.h
regress/case-ptrbaddom.err [new file with mode: 0644]
regress/case-ptrbaddom.out [new file with mode: 0644]
regress/case-ptrbaddom.sys [new file with mode: 0644]
src/adns.h
src/query.c

index 3989b51a42eac257fe5e93e1214a5e0eba9b9c84..942f20bd2c3fc87c873580fab3d69f11f062abc1 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,11 +1,14 @@
 adns (0.7) BETA; urgency=medium
 
 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).
   * 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.
   * 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.
 
  --
 
 
  --
 
index 81cff540c67ed423d6be74ec0c923fcfaa0b2417..3fa1adb7935730c38d126a80b82bf7bc798cc066 100644 (file)
@@ -62,7 +62,7 @@ char *xstrsave(const char *str) {
   return p;
 }
 
   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;
   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 *const **argv_p,
                           const char *value) {
   const struct optioninfo *oip;
+  const char *arg2;
   int invert;
 
   if (arg[0] == '-' || arg[0] == '+') {
   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);
       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;
       } 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");
     } 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);
          }
          } 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);
          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);
        }
       }
     }
        }
       }
     }
index 46d5606d5ada55b77a7a0480843f1f34d684a16f..af8afbdec13b3f94b1bb466d44ed1a1018d9261a 100644 (file)
@@ -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" },
     "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",
 
   { ot_desconly, "per-query binary options:" },
   { ot_flag,             "Use the search list",
@@ -192,6 +194,15 @@ static void printusage(void) {
                 oip->desc);
        }
        break;
                 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;
       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);
 }
 
   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);
   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 : "");
 }
 
           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);
   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;
     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);
     if (invert) noninvert(oip);
-    oip->func(oip,arg);
+    oip->func(oip,arg,arg2);
     return;
   default:
     abort();
     return;
   default:
     abort();
index cc5dc122f2846f194aaee48244063b43b9e7b0d7..a25c894e8a20afad9a74449a4c384bc38772fdeb 100644 (file)
@@ -79,7 +79,7 @@ static void prep_query(struct query_node **qun_r, int *quflags_r) {
   *qun_r= qun;
 }
   
   *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;
   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);
 }
 
   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;
 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);
 }
 
   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);
 }
 
   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;
   struct query_node *qun;
 
   for (qun= outstanding.head;
index 93a7608b11bfc8213684c009df1bb4daf5da2430..1918047a8dd6faf2cc27ac7d62395a0aa681b74f 100644 (file)
 /* declarations related to option processing */
 
 struct optioninfo;
 /* 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,
 
 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;
   } 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 };
 };
 
 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 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);
 
 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 */
 
 
 /* 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 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;
 /* 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 (file)
index 0000000..e69de29
diff --git a/regress/case-ptrbaddom.out b/regress/case-ptrbaddom.out
new file mode 100644 (file)
index 0000000..3be9371
--- /dev/null
@@ -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 (file)
index 0000000..6b12372
--- /dev/null
@@ -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
index a1e0877c1327251d8a722d706cd99a456026c89d..6c07e64fd7daab798f5f91c69dbabee16a4758ce 100644 (file)
@@ -511,6 +511,19 @@ int adns_submit_reverse(adns_state ads,
  * addr->sa_family must be AF_INET or you get ENOSYS.
  */
 
  * 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
+ *   <reversed-address>.<zone>
+ * 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.
 void adns_finish(adns_state ads);
 /* You may call this even if you have queries outstanding;
  * they will be cancelled.
index 5e345ae72f5f4101e356c367be6489509b8b26f0..a8423d7c36e3a7bdd6c13c104885d83a10a5bcf3 100644 (file)
@@ -267,25 +267,47 @@ int adns_submit(adns_state ads,
   return r;
 }
 
   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;
   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);
 
   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,
 }
 
 int adns_synchronous(adns_state ads,