Patch: Elm ME+ 2.5 PLalpha46 -> Elm ME+ 2.5 PLalpha47 [6/7] (5/5)
From
Kari Hurtta@21:1/5 to
All on Sat Feb 10 14:47:10 2018
[continued from previous message]
+ walk_ptr += sizeof (X.ip4addr);
+ size_left -= sizeof (X.ip4addr);
+
+ addr = inet_ntop(AF_INET,& (X.ip4addr),
+ address,sizeof address);
+
+ if (addr) {
+ printf(" = %s",addr);
+ }
+ }
+
+ break;
+ case ns_t_ns:
+ printf(" name server");
+
+ if (size_left > 0) {
+ char domain_name[1024];
+ int compressed_len;
+
+ errno = 0;
+ compressed_len =
+ ns_name_uncompress(ns_msg_base((*parsed)),
+ ns_msg_end((*parsed)),
+ walk_ptr,
+ domain_name,
+ sizeof domain_name);
+
+ if (compressed_len < 0) {
+ printf(", failed to expand name");
+ break;
+ }
+
+ walk_ptr += compressed_len;
+ size_left -= compressed_len;
+
+ printf(" = %s",domain_name);
+ }
+
+
+ break;
+ case ns_t_cname:
+ printf(" canonical name");
+
+ if (size_left > 0) {
+ char domain_name[1024];
+ int compressed_len;
+
+ errno = 0;
+ compressed_len =
+ ns_name_uncompress(ns_msg_base((*parsed)),
+ ns_msg_end((*parsed)),
+ walk_ptr,
+ domain_name,
+ sizeof domain_name);
+
+ if (compressed_len < 0) {
+ printf(", failed to expand name");
+ break;
+ }
+
+ walk_ptr += compressed_len;
+ size_left -= compressed_len;
+
+ printf(" = %s",domain_name);
+ }
+
+ break;
+ case ns_t_mx:
+ printf(" mail handler");
+
+ if (size_left > 2) {
+ int precedence;
+ char domain_name[1024];
+ int compressed_len;
+
+ precedence = ns_get16(walk_ptr);
+ walk_ptr += 2;
+ size_left -= 2;
+
+ compressed_len =
+ ns_name_uncompress(ns_msg_base((*parsed)),
+ ns_msg_end((*parsed)),
+ walk_ptr,
+ domain_name,
+ sizeof domain_name);
+
+ if (compressed_len < 0) {
+ printf(", failed to expand name");
+ break;
+ }
+
+ walk_ptr += compressed_len;
+ size_left -= compressed_len;
+
+ printf(" = %s precedence=%d",domain_name,precedence);
+ }
+
+ break;
+ case ns_t_aaaa:
+ printf(" IPv6 address");
+
+ if (size_left >= sizeof (X.ip6addr)) {
+ char address[256];
+ const char *addr;
+
+ memcpy(X.buffer,walk_ptr,sizeof (X.ip6addr));
+
+ walk_ptr += sizeof (X.ip6addr);
+ size_left -= sizeof (X.ip6addr);
+
+ addr = inet_ntop(AF_INET6,& (X.ip6addr),
+ address,sizeof address);
+
+ if (addr) {
+ printf(" = %s",addr);
+ }
+ }
+
+ break;
+
+ case ns_t_txt:
+ printf(" text record");
+
+ n = 0;
+ while (size_left > 0) {
+ char text[256];
+
+ int len = *walk_ptr;
+
+ if (len > size_left + 1) {
+ printf(", failed to read text record");
+ break;
+ }
+
+ walk_ptr ++;
+ size_left --;
+
+ memcpy(text,walk_ptr,len);
+ text[len] = '\0';
+
+ walk_ptr += len;
+ size_left -= len;
+
+ if (n++ > 0) {
+ printf(",\n text record");
+ }
+
+ printf(" = %s",text);
+ }
+
+ break;
+
+ case ns_t_srv:
+ printf(" server");
+
+ if (size_left > 6) {
+ int priority, weight, port;
+ char domain_name[1024];
+ int compressed_len;
+
+ priority = ns_get16(walk_ptr);
+ walk_ptr += 2;
+ size_left -= 2;
+
+ weight = ns_get16(walk_ptr);
+ walk_ptr += 2;
+ size_left -= 2;
+
+ port = ns_get16(walk_ptr);
+ walk_ptr += 2;
+ size_left -= 2;
+
+ compressed_len =
+ ns_name_uncompress(ns_msg_base((*parsed)),
+ ns_msg_end((*parsed)),
+ walk_ptr,
+ domain_name,
+ sizeof domain_name);
+
+ if (compressed_len < 0) {
+ printf(", failed to expand name");
+ break;
+ }
+
+ walk_ptr += compressed_len;
+ size_left -= compressed_len;
+
+ printf(" = %s priority=%d weight=%d port=%d",
+ domain_name,priority,weight,port);
+ }
+ break;
+
+ case ns_t_ptr:
+ printf(" domain name");
+
+ if (size_left > 0) {
+ char domain_name[1024];
+ int compressed_len;
+
+ errno = 0;
+ compressed_len =
+ ns_name_uncompress(ns_msg_base((*parsed)),
+ ns_msg_end((*parsed)),
+ walk_ptr,
+ domain_name,
+ sizeof domain_name);
+
+ if (compressed_len < 0) {
+ printf(", failed to expand name");
+ break;
+ }
+
+ walk_ptr += compressed_len;
+ size_left -= compressed_len;
+
+ printf(" = %s",domain_name);
+ }
+
+
+ break;
+ }
+
+ if (0 != size_left) {
+ printf(", %d trailing bytes",size_left);
+ }
+
+ printf("\n");
+ }
+
+ }
+ }
+
+ #if defined(__STDC__)
+ int same_question_rr(ns_rr *rr1, ns_rr *rr2);
+ #endif
+
+ int same_question_rr(rr1,rr2)
+ ns_rr *rr1;
+ ns_rr *rr2;
+ {
+ char *name1 = ns_rr_name((*rr1));
+ char *name2 = ns_rr_name((*rr2));
+ ns_class recclass1 = ns_rr_class((*rr1));
+ ns_class recclass2 = ns_rr_class((*rr2));
+ ns_type rectype1 = ns_rr_type((*rr1));
+ ns_type rectype2 = ns_rr_type((*rr2));
+
+ if (! name1 || ! name2) {
+ fprintf(stderr,"same_question_rr: no name\n");
+ return 0;
+ }
+
+ if (0 != strcmp(name1,name2)) {
+ fprintf(stderr,"same_question_rr: name mismatch: %s <> %s\n",
+ name1,name2);
+ return 0;
+ }
+
+ if (recclass1 != recclass2) {
+ fprintf(stderr,"same_question_rr: %s: class mismatch: %d <> %d\n",
+ name1,recclass1,recclass2);
+ return 0;
+ }
+
+ if (rectype1 != rectype2) {
+ fprintf(stderr,"same_question_rr: %s: rectype mismatch: %d <> %d\n",
+ name1,rectype1,rectype2);
+ return 0;
+ }
+
+ return 1;
+ }
+
+ #if defined(__STDC__)
+ int query_it (const char *name, ns_type q_type, char *domain);
+ #endif
+ int query_it(name,q_type,domain)
+ const char *name;
+ ns_type q_type;
+ char *domain;
+ {
+ const char * name1 = name;
+ int r = 0;
+ int res;
+
+ unsigned char query[1024];
+ int qlen;
+ ns_msg parsed_query;
+ int count,count1,count2;
+
+ u_int16_t id1,id2;
+ int recnum;
+
+ unsigned char answer[1024];
+ int anslen;
+ ns_msg parsed_answer;
+ int trailing_dot = 0;
+
+ int a = strlen(name);
+ ns_rcode rcode;
+ char * name_buffer = NULL;
+
+ errno = 0;
+
+ if (a > 0 && '.' == name[a-1]) {
+ trailing_dot = 1;
+
+ if (domain) {
+ fprintf(stderr, "%s: internal error - trailing dot and domain %s set\n",
+ name,domain);
+
+ r = -1;
+ goto fail;
+ }
+
+ } else if (domain && domain[0]) {
+ int d = strlen(domain);
+
+ name_buffer = malloc(a+d+2);
+
+ if (!name_buffer) {
+ int err = errno;
+ fprintf(stderr, "malloc %s.%s failed",
+ name,domain);
+ if (0 != err) {
+ fprintf(stderr," errno=%d %s",err,strerror(err));
+ }
+
+ r = -1;
+ goto fail;
+ }
+
+ memcpy(name_buffer,name,a);
+ name_buffer[a] = '.';
+ memcpy(name_buffer+a+1,domain,d);
+ name_buffer[a+d+1] = '\0';
+
+ name1 = name_buffer;
+ }
+
+ errno = 0;
+
+ qlen = res_mkquery(QUERY,name1,ns_c_in,q_type,
+ NULL,0 /* Only used with IQUERY */,
+ NULL /* Only used with dynamic update */,
+ query, sizeof query);
+
+ if (qlen < 0) {
+ int err = errno;
+ fprintf(stderr, "res_mkquery %s: h_errno=%d ",
+ name1,h_errno);
+ if (0 != err) {
+ fprintf(stderr," errno=%d %s",err,strerror(err));
+ }
+
+ fprintf(stderr, "\n");
+ r = -1;
+ goto fail;
+ }
+
+ printf("res_mkquery %s: query %d bytes\n",
+ name1,qlen);
+
+ errno = 0;
+ res = ns_initparse(query,qlen,&parsed_query);
+ if (res < 0) {
+ int err = errno;
+
+ fprintf (stderr,"%s: failed to parse query (ns_initparse)",
+ name1);
+
+ if (0 != err) {
+ fprintf(stderr," errno=%d %s",err,strerror(err));
+ }
+
+ fprintf(stderr, "\n");
+ r = -1;
+ goto fail;
+ }
+
+ print_parsed(name1,&parsed_query,"query");
+
+ anslen = res_send(query,qlen,answer,sizeof answer);
+
+ if (anslen < 0) {
+ int err = errno;
+ fprintf(stderr, "%s: h_errno=%d",name1,h_errno);
+
+ switch(h_errno) {
+ case HOST_NOT_FOUND:
+ fprintf(stderr, " name not found");
+ break;
+ case NO_DATA:
+ fprintf(stderr, " no %s record",name1);
+ break;
+ case TRY_AGAIN:
+ fprintf(stderr, " not found yet");
+ break;
+ }
+
+ if (0 != err) {
+ fprintf(stderr," errno=%d %s",err,strerror(err));
+ }
+
+ if (err == ECONNREFUSED)
+ r = -1;
+ else if (err == ETIMEDOUT)
+ r = -3;
+ else if (TRY_AGAIN == h_errno)
+ r = -3;
+
+ fprintf(stderr, "\n");
+ goto fail;
+ }
+
+ printf("res_send %s: answer %d bytes\n",
+ name1,anslen);
+
+ errno = 0;
+ res = ns_initparse(answer,anslen,&parsed_answer);
+ if (res < 0) {
+ int err = errno;
+
+ fprintf (stderr,"%s: failed to parse answer (ns_initparse)",
+ name1);
+
+ if (0 != err) {
+ fprintf(stderr," errno=%d %s",err,strerror(err));
+ }
+
+ fprintf(stderr, "\n");
+ r = -1;
+ goto fail;
+ }
+
+ print_parsed(name1,&parsed_answer,"answer");
+
+ id1 = ns_msg_id(parsed_query);
+ id2 = ns_msg_id(parsed_answer);
+
+ if (id1 != id2) {
+ fprintf(stderr, "%s id mismatch: query %d <> answer %d\n",
+ name1,id1,id2);
+ r = -1;
+ goto fail;
+ }
+
+ count = ns_msg_count(parsed_query, ns_s_qd);
+ count1 = ns_msg_count(parsed_answer, ns_s_qd);
+
+ if (count != 1 || count1 != 1) {
+ fprintf(stderr, "%s -- on query %d records -- on aswer %d records on question section\n",
+ name1,count,count1);
+ r = -1;
+ goto fail;
+
+ } else {
+ ns_rr rr1;
+ ns_rr rr2;
+
+ res = ns_parserr(&parsed_query,ns_s_qd,0,&rr1);
+ if (res < 0) {
+ fprintf (stderr,"%s: failed to parse question (ns_parserr)\n",name1); + r = -1;
+ goto fail;
+ }
+
+ res = ns_parserr(&parsed_answer,ns_s_qd,0,&rr2);
+ if (res < 0) {
+ fprintf (stderr,"%s: failed to parse answer (ns_parserr)\n",name1);
+ r = -1;
+ goto fail;
+ }
+
+ if (! same_question_rr(&rr1,&rr2)) {
+ fprintf (stderr,"%s: answer does not match to question\n",name1);
+ r = -1;
+ goto fail;
+ }
+
+ }
+
+ rcode = ns_msg_getflag(parsed_answer, ns_f_rcode);
+ switch (rcode) {
+ case ns_r_noerror:
+ r = 2;
+ break;
+ case ns_r_formerr: fprintf(stderr,"%s: format error\n",name1);
+ r = -1;
+ goto fail;
+ case ns_r_servfail: fprintf(stderr,"%s: server failure\n",name1);
+ r = -1;
+ goto fail;
+ case ns_r_nxdomain: fprintf(stderr,"%s: name not found\n", name1);
+ r = 0;
+ goto fail;
+ case ns_r_notimpl: fprintf(stderr,"%s: not implemented\n",name1);
+ r = -1;
+ goto fail;
+ case ns_r_refused: fprintf(stderr,"%s: operation refused\n",name1);
+ r = 0;
+ goto fail;
+ default:
+ fprintf(stderr,"%s: unexpected rcode %d\n",name1,rcode);
+ r = -1;
+ goto fail;
+ }
+
+ count2 = ns_msg_count(parsed_answer, ns_s_an);
+ for (recnum = 0; recnum < count2 && r != 1; recnum++) {
+ ns_rr rr;
+
+ r = ns_parserr(&parsed_answer,ns_s_an,recnum,&rr);
+ if (r < 0) {
+ fprintf (stderr,"%s: failed to parse answer (ns_parserr), %d\n",name1, recnum);
+ r = -1;
+ goto fail;
+ }
+
+ if (ns_rr_class(rr) == ns_c_in &&
+ (ns_rr_type(rr) == q_type ||
+ ns_rr_type(rr) == ns_t_cname) &&
+ ns_rr_name(rr)) {
+
+ if (0 == strcmp(name1, ns_rr_name(rr))) {
+
+ printf ("%s: got answer for %s\n",name,name1);
+ r = 1;
+ } else if (trailing_dot && 0 == strncmp(name,ns_rr_name(rr),a-1)) {
+ printf ("%s: %s matches without trailing dot\n",name,ns_rr_name(rr)); + r = 1;
+ } else if (!name1[0] && 0 == strcmp(ns_rr_name(rr),".")) {
+ printf ("empty name matches to %s\n",ns_rr_name(rr));
+ r = 1;
+ }
+ }
+ }
+
+ fail:
+ if (name_buffer)
+ free(name_buffer);
+ return r;
+ }
+
+ #if defined(__STDC__)
+ int main (int argc, char * argv[]);
+ #endif
+
+ int main (argc,argv)
+ int argc;
+ char * argv[];
+ {
+ int r = 0;
+
+ unsigned char answer[1024];
+ int anslen;
+
+ unsigned char query[1024];
+ int qlen;
+
+ ns_msg parsed_query;
+ ns_type q_type;
+
+ char * name;
+
+
+ if (argc != 4) {
+ USAGE:
+ fprintf(stderr, "Usage: %s [query|search] [a|ns|mx|aaaa|txt|srv|ptr] <name>\n",argv[0]);
+ exit(1);
+ }
+
+ if (0 == strcasecmp(argv[2],"a"))
+ q_type = ns_t_a;
+ else if (0 == strcasecmp(argv[2],"ns"))
+ q_type = ns_t_ns;
+ else if (0 == strcasecmp(argv[2],"cname"))
+ q_type = ns_t_cname;
+ else if (0 == strcasecmp(argv[2],"mx"))
+ q_type = ns_t_mx;
+ else if (0 == strcasecmp(argv[2],"aaaa"))
+ q_type = ns_t_aaaa;
+ else if (0 == strcasecmp(argv[2],"txt"))
+ q_type = ns_t_txt;
+ else if (0 == strcasecmp(argv[2],"srv"))
+ q_type = ns_t_srv;
+ else if (0 == strcasecmp(argv[2],"ptr"))
+ q_type = ns_t_ptr;
+ else
+ goto USAGE;
+
+ name = argv[3];
+
+ if (0 == strcmp(argv[1],"query")) {
+ r = query_it(name,q_type,NULL);
+
+ if (r < 0) {
+
+ if (-3 == r)
+ exit(3);
+
+ exit(2);
+ }
+
+ } else if (0 == strcmp(argv[1],"search")) {
+
+ /* This should be similar than res_search */
+
+ int dots = 0;
+ char *c;
+ char * found_dot = NULL;
+ const char * alias;
+
+ res_init();
+
+ for (c = name;*c; c++) {
+ if ('.' == *c) {
+ dots++;
+ found_dot = c;
+ }
+ }
+
+ if (found_dot && !found_dot[1]) {
+ printf("%s: trailing dot\n",name);
+ r = query_it(name,q_type,NULL);
+
+ if (r < 0) {
+
+ if (-3 == r)
+ exit(3);
+
+ exit(2);
+ }
+
+ } else if (!dots && (alias = hostalias(name))) {
+ printf("%s: No dots, searching alias: %s\n",
+ name,alias);
+
+ r = query_it(alias,q_type,NULL);
+
+ if (r < 0) {
+ exit(2);
+ }
+
+ } else {
+ char * default_domain_searched = NULL;
+ int root_searched = 0;
+
+ if (!dots && 0 != (_res.options & RES_DEFNAMES)) {
+ printf("%s: No dots, (RES_DEFNAMES) searching from default domain: %s\n",
+ name,_res.defdname);
+
+ default_domain_searched = _res.defdname;
+
+ if ( ! _res.defdname[0] || 0 == strcmp(_res.defdname,".")) {
+ printf(" ... default domain is root\n");
+ root_searched = 1;
+ }
+
+ r = query_it(name,q_type,_res.defdname);
+
+ } else if (dots >= _res.ndots) {
+ printf("%s: %d dots, doing absolute query (ndots:%d)\n",
+ name,dots,_res.ndots);
+
+ r = query_it(name,q_type,NULL);
+ root_searched = 1;
+
+ if (r < 0) {
+ exit(2);
+ }
+ }
+
+ if (!r && 0 != (_res.options & RES_DNSRCH) &&
+ (dots ||
+ 0 != (_res.options & RES_DEFNAMES))
+ ) {
+ int x;
+
+ printf("%s: %d dots%s, (RES_DNSRCH) using search list\n",
+ name,dots,
+ 0 != (_res.options & RES_DEFNAMES) ? " (RES_DEFNAMES)" : "");
+
+ for (x = 0 ;
+ x < (sizeof _res.dnsrch) / sizeof (_res.dnsrch[0]) &&
+ _res.dnsrch[x] && !r; x++) {
+
+ if (default_domain_searched &&
+ 0 == strcmp(default_domain_searched,
+ _res.dnsrch[x])) {
+
+ printf ("skipping %d: %s (default domain already searched)\n",
+ x, _res.dnsrch[x]);
+
+ } else {
+ int is_root =
+ ( ! _res.dnsrch[x][0] || 0 == strcmp( _res.dnsrch[x],"."));
+
+ if (root_searched && is_root) {
+ printf ("skipping %d: %s (root already searched)\n",
+ x, _res.dnsrch[x]);
+ } else {
+
+ printf ("searching %d: %s%s\n",x, _res.dnsrch[x],
+ is_root ? " (is root)" : "");
+
+ r = query_it(name,q_type,_res.dnsrch[x]);
+
+ if (is_root)
+ root_searched = 1;
+
+ if (r < 0) {
+
+ if (-3 == r)
+ exit(3);
+
+ exit(2);
+ }
+ }
+ }
+ }
+ }
+
+
+ if (!r && !root_searched
+
+ #ifdef RES_NOTLDQUERY
+ && (dots || 0 == (_res.options & RES_NOTLDQUERY))
+ #endif
+ ) {
+
+ printf("%s: doing absolute query\n",
+ name);
+
+ r = query_it(name,q_type,NULL);
+ root_searched = 1;
+
+ if (r < 0) {
+ exit(2);
+ }
+ }
+ }
+
+ } else
+ goto USAGE;
+
+ if (!r) {
+ fprintf(stderr,"%s not found\n",name);
+ exit(2);
+ } else if (2 == r) {
+ fprintf(stderr,"%s: no %s record\n",
+ name,argv[2]);
+ exit(2);
+ }
+
+ exit(0);
+ }
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)