diff options
Diffstat (limited to 'toys/pending/host.c')
-rw-r--r-- | toys/pending/host.c | 131 |
1 files changed, 47 insertions, 84 deletions
diff --git a/toys/pending/host.c b/toys/pending/host.c index 178a4da7..50de1d34 100644 --- a/toys/pending/host.c +++ b/toys/pending/host.c @@ -67,12 +67,11 @@ static const char rct[16][32] = { void host_main(void) { - int verbose=(toys.optflags & (FLAG_a|FLAG_v)), type; - char *name, *nsname; - int i, j, ret, sec, count, rcode, qlen, alen, pllen = 0; + int verbose=(toys.optflags & (FLAG_a|FLAG_v)), type, + i, j, ret, sec, count, rcode, qlen, alen, pllen = 0; unsigned ttl, pri, v[5]; unsigned char qbuf[280], abuf[512], *p; - char rrname[256], plname[640], ptrbuf[64]; + char *name, *nsname, rrname[256], plname[640], ptrbuf[64]; struct addrinfo *ai, iplit_hints = { .ai_flags = AI_NUMERICHOST }; name = *toys.optargs; @@ -80,16 +79,14 @@ void host_main(void) if (!TT.type_str && (toys.optflags & FLAG_a)) TT.type_str = "255"; if (!getaddrinfo(name, 0, &iplit_hints, &ai)) { - switch (ai->ai_family) { - unsigned char *a; - static const char xdigits[] = "0123456789abcdef"; - case AF_INET: + unsigned char *a; + static const char xdigits[] = "0123456789abcdef"; + + if (ai->ai_family == AF_INET) { a = (void *)&((struct sockaddr_in *)ai->ai_addr)->sin_addr; - snprintf(ptrbuf, sizeof ptrbuf, - "%d.%d.%d.%d.in-addr.arpa", + snprintf(ptrbuf, sizeof(ptrbuf), "%d.%d.%d.%d.in-addr.arpa", a[3], a[2], a[1], a[0]); - break; - case AF_INET6: + } else if (ai->ai_family == AF_INET6) { a = (void *)&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; for (j=0, i=15; i>=0; i--) { ptrbuf[j++] = xdigits[a[i]&15]; @@ -98,17 +95,13 @@ void host_main(void) ptrbuf[j++] = '.'; } strcpy(ptrbuf+j, "ip6.arpa"); - break; } name = ptrbuf; if (!TT.type_str) TT.type_str="12"; - } else { - if (!TT.type_str) TT.type_str="1"; - } + } else if (!TT.type_str) TT.type_str="1"; - if (TT.type_str[0]-'0' < 10u) { - type = atoi(TT.type_str); - } else { + if (TT.type_str[0]-'0' < 10u) type = atoi(TT.type_str); + else { type = -1; for (i=0; i < sizeof rrt / sizeof *rrt; i++) { if (rrt[i].name && !strcasecmp(TT.type_str, rrt[i].name)) { @@ -117,76 +110,57 @@ void host_main(void) } } if (!strcasecmp(TT.type_str, "any")) type = 255; - if (type < 0) { - fprintf(stderr, "Invalid query type: %s\n", TT.type_str); - goto out_error; - } + if (type < 0) error_exit("Invalid query type: %s", TT.type_str); } qlen = res_mkquery(0, name, 1, type, 0, 0, 0, qbuf, sizeof qbuf); - if (qlen < 0) { - fprintf(stderr, "Invalid query parameters: %s", name); - goto out_error; - } + if (qlen < 0) error_exit("Invalid query parameters: %s", name); if (nsname) { struct addrinfo ns_hints = { .ai_socktype = SOCK_DGRAM }; - if ((ret = getaddrinfo(nsname, "53", &ns_hints, &ai)) < 0) { - fprintf(stderr, "Error looking up server name: %s\n", - gai_strerror(ret)); - goto out_error; - } + + if ((ret = getaddrinfo(nsname, "53", &ns_hints, &ai)) < 0) + error_exit("Error looking up server name: %s", gai_strerror(ret)); int s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (s < 0 || connect(s, ai->ai_addr, ai->ai_addrlen) < 0) { - fprintf(stderr, "Socket error: %s\n", strerror(errno)); - goto out_error; - } - setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, - &(struct timeval){ .tv_sec = 5 }, - sizeof (struct timeval)); + if (s < 0 || connect(s, ai->ai_addr, ai->ai_addrlen) < 0) + perror_exit("Socket error"); + setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &(struct timeval){ .tv_sec = 5 }, + sizeof(struct timeval)); printf("Using domain server %s:\n", nsname); send(s, qbuf, qlen, 0); alen = recv(s, abuf, sizeof abuf, 0); - } else { - alen = res_send(qbuf, qlen, abuf, sizeof abuf); - } + } else alen = res_send(qbuf, qlen, abuf, sizeof abuf); - if (alen < 12) { - fprintf(stderr, "Host not found, try again.\n"); - goto out_error; - } + if (alen < 12) error_exit("Host not found."); rcode = abuf[3] & 15; if (verbose) { printf("rcode = %d (%s), ancount = %d\n", rcode, rct[rcode], 256*abuf[6] + abuf[7]); - if (!(abuf[2] & 4)) - printf("The following answer is not authoritative:\n"); + if (!(abuf[2] & 4)) printf("The following answer is not authoritative:\n"); } - if (rcode) { - fprintf(stderr, "Host not found.\n"); - if (!verbose) goto out_error; - } + if (rcode) error_exit("Host not found."); p = abuf + 12; for (sec=0; sec<4; sec++) { count = 256*abuf[4+2*sec] + abuf[5+2*sec]; - if (verbose && count>0 && sec>1) { + if (verbose && count>0 && sec>1) puts(sec==2 ? "For authoritative answers, see:" : "Additional information:"); - } + for (; count--; p += pllen) { - p += dn_expand(abuf, abuf+alen, p, rrname, sizeof rrname); - type = 256*p[0] + p[1]; + p += dn_expand(abuf, abuf+alen, p, rrname, sizeof(rrname)); + type = (p[0]<<8) + p[1]; p += 4; if (!sec) continue; - ttl = 16777216*p[0] + 65536*p[1] + 256*p[2] + p[3]; + ttl = (p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]; p += 4; - pllen = 256*p[0] + p[1]; + pllen = (p[0]<<8) + p[1]; p += 2; - switch (type<sizeof rrt/sizeof *rrt ? rrt[type].pl : 0) { + + switch (type<sizeof(rrt)/sizeof(*rrt) ? rrt[type].pl : 0) { case PL_IP: inet_ntop(rrt[type].af, p, plname, sizeof plname); break; @@ -200,12 +174,10 @@ void host_main(void) i = dn_expand(abuf, abuf+alen, p, plname, sizeof plname - 1); strcat(plname, " "); i += dn_expand(abuf, abuf+alen, p+i, plname+strlen(plname), - sizeof plname-strlen(plname)); + sizeof(plname)-strlen(plname)); for (j=0; j<5; j++) - v[j] = 16777216u*p[i+4*j] + 65536*p[1+i+4*j] - + 256*p[2+i+4*j] + p[3+i+4*j]; - snprintf(plname+strlen(plname), - sizeof plname-strlen(plname), + v[j] = (p[i+4*j]<<24)+(p[1+i+4*j]<<16)+(p[2+i+4*j]<<8)+p[3+i+4*j]; + snprintf(plname+strlen(plname), sizeof(plname)-strlen(plname), "(\n\t\t%u\t;serial (version)\n" "\t\t%u\t;refresh period\n" "\t\t%u\t;retry interval\n" @@ -214,38 +186,29 @@ void host_main(void) "\t\t)", v[0], v[1], v[2], v[3], v[4]); break; case PL_MX: - pri = 256*p[0] + p[1]; - snprintf(plname, sizeof plname, - verbose ? "%d " : "(pri=%d) by ", pri); - dn_expand(abuf, abuf+alen, p+2, - plname+strlen(plname), + pri = (p[0]<<8)+p[1]; + snprintf(plname, sizeof(plname), verbose ? "%d " : "(pri=%d) by ", pri); + dn_expand(abuf, abuf+alen, p+2, plname+strlen(plname), sizeof plname - strlen(plname)); break; case PL_SRV: - for (j=0; j<3; j++) - v[j] = 256*p[2*j] + p[1+2*j]; - snprintf(plname, sizeof plname, - "%u %u %u ", v[0], v[1], v[2]); - dn_expand(abuf, abuf+alen, p+6, - plname+strlen(plname), + for (j=0; j<3; j++) v[j] = (p[2*j]<<8) + p[1+2*j]; + snprintf(plname, sizeof(plname), "%u %u %u ", v[0], v[1], v[2]); + dn_expand(abuf, abuf+alen, p+6, plname+strlen(plname), sizeof plname - strlen(plname)); break; default: printf("%s unsupported RR type %u\n", rrname, type); continue; } - if (verbose) { - printf("%s\t%u\t%s %s\t%s\n", - rrname, ttl, "IN", rrt[type].name, plname); - } else if (rrt[type].msg) { + + if (verbose) + printf("%s\t%u\tIN %s\t%s\n", rrname, ttl, rrt[type].name, plname); + else if (rrt[type].msg) printf("%s %s %s\n", rrname, rrt[type].msg, plname); - } } if (!verbose && sec==1) break; } - toys.exitval = rcode; - return; -out_error: - toys.exitval = 1; + toys.exitval = rcode; } |