Date: Mon, 30 Mar 2009 22:56:34 GMT From: Aragon Gouveia <aragon@phat.za.net> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/133227: Add support for SLD whois server lookups and IPv6 address lookups Message-ID: <200903302256.n2UMuYcs034597@www.freebsd.org> Resent-Message-ID: <200903302300.n2UN09PK019585@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 133227 >Category: bin >Synopsis: Add support for SLD whois server lookups and IPv6 address lookups >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Mar 30 23:00:09 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Aragon Gouveia >Release: 7.1-STABLE >Organization: >Environment: FreeBSD igor.geek.sh 7.1-STABLE FreeBSD 7.1-STABLE #3: Wed Mar 11 14:24:50 SAST 2009 root@igor.geek.sh:/usr/src/sys/amd64/compile/IGOR amd64 >Description: When performing a domain name whois lookup, whois(1) performs a DNS lookup on <tld>.whois-servers.net to discover the authoritative whois server address. This does not cater for some TLD registries that do not operate a TLD whois server, but operate one or many SLD whois servers below said TLD. For example: domain test.co.za $ host za.whois-servers.net Host za.whois-servers.net not found: 3(NXDOMAIN) $ host co.za.whois-servers.net co.za.whois-servers.net is an alias for whois.coza.net.za. $ whois test.co.za whois: za.whois-servers.net: hostname nor servname provided, or not known The attached patch resolves this by first attempting to resolve co.za.whois-servers.net and using it if it resolves. If not found, it will attempt za.whois-servers.net as normal. In addition I have also integrated PR bin/128725 into my patch so that whois treats IPv6 address lookups the same as IPv4 addresses (sending the query to ARIN's whois server). >How-To-Repeat: >Fix: Patch attached with submission follows: --- whois.c.orig 2007-04-14 16:32:48.000000000 +0200 +++ whois.c 2009-03-31 00:42:33.000000000 +0200 @@ -91,7 +91,7 @@ FNICHOST, NULL }; const char *port = DEFAULT_PORT; -static char *choose_server(char *); +static struct addrinfo *choose_hostinfo(const char *domain, char const **hostname); static struct addrinfo *gethostinfo(char const *host, int exit_on_error); static void s_asprintf(char **ret, const char *format, ...) __printflike(2, 3); static void usage(void); @@ -187,7 +187,6 @@ */ if (host == NULL && country == NULL) { use_qnichost = 1; - host = NICHOST; if (!(flags & WHOIS_QUICK)) flags |= WHOIS_RECURSE; } @@ -195,29 +194,41 @@ if (country != NULL) { s_asprintf(&qnichost, "%s%s", country, QNICHOST_TAIL); whois(*argv, qnichost, flags); - } else if (use_qnichost) - if ((qnichost = choose_server(*argv)) != NULL) - whois(*argv, qnichost, flags); - if (qnichost == NULL) + free(qnichost); + qnichost = NULL; + } else if (use_qnichost) { + whois(*argv, NULL, flags); + } else { whois(*argv, host, flags); - free(qnichost); - qnichost = NULL; + } argv++; } exit(0); } /* - * This function will remove any trailing periods from domain, after which it - * returns a pointer to newly allocated memory containing the whois server to - * be queried, or a NULL if the correct server couldn't be determined. The - * caller must remember to free(3) the allocated memory. + * This function takes the trailing subdomains of a domain + * prepends them to .whois-servers.net and attempts to resolve + * them. Starting from the highest it removes more subdomain + * parts until a successful resolution is found, or exits + * if none are found. + * + * However, before doing so it checks if we're doing a NORID, + * IP address, or non-hostname lookup. If so, it resolves + * the relevant hostname. */ -static char * -choose_server(char *domain) +static struct addrinfo * +choose_hostinfo(const char *domain, char const **hostname) { - char *pos, *retval; + char *pos, *last, *lookup; + struct addrinfo *res; + if (strchr(domain, ':')) { + s_asprintf(&lookup, "%s", ANICHOST); + res = gethostinfo(lookup, 1); + *hostname = lookup; + return res; + } for (pos = strchr(domain, '\0'); pos > domain && *--pos == '.';) *pos = '\0'; if (*domain == '\0') @@ -225,18 +236,35 @@ if (strlen(domain) > sizeof("-NORID")-1 && strcasecmp(domain + strlen(domain) - sizeof("-NORID") + 1, "-NORID") == 0) { - s_asprintf(&retval, "%s", NORIDHOST); - return (retval); + s_asprintf(&lookup, "%s", NORIDHOST); + res = gethostinfo(lookup, 1); + *hostname = lookup; + return res; } - while (pos > domain && *pos != '.') - --pos; - if (pos <= domain) - return (NULL); - if (isdigit((unsigned char)*++pos)) - s_asprintf(&retval, "%s", ANICHOST); - else - s_asprintf(&retval, "%s%s", pos, QNICHOST_TAIL); - return (retval); + if (!(last = strrchr(domain, '.'))) { + s_asprintf(&lookup, "%s", NICHOST); + res = gethostinfo(lookup, 1); + *hostname = lookup; + return res; + } + pos = last+1; + if (isdigit((unsigned char)*pos)) { + s_asprintf(&lookup, "%s", ANICHOST); + res = gethostinfo(lookup, 1); + *hostname = lookup; + return res; + } + while (pos = strchr(domain, '.')) { + domain = ++pos; + s_asprintf(&lookup, "%s%s", pos, QNICHOST_TAIL); + res = gethostinfo(lookup, pos>last?1:0); + if (res) { + *hostname = lookup; + break; + } else + free(lookup); + } + return res; } static struct addrinfo * @@ -251,9 +279,10 @@ hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(host, port, &hints, &res); if (error) { - warnx("%s: %s", host, gai_strerror(error)); - if (exit_on_error) + if (exit_on_error) { + warnx("%s: %s", host, gai_strerror(error)); exit(EX_NOHOST); + } return (NULL); } return (res); @@ -280,12 +309,17 @@ { FILE *sfi, *sfo; struct addrinfo *hostres, *res; - char *buf, *host, *nhost, *p; + char *fhost, *buf, *host, *nhost, *p; int i, s; size_t c, len; s = -1; - hostres = gethostinfo(hostname, 1); + fhost = NULL; + if (hostname == NULL) { + hostres = choose_hostinfo(query, &hostname); + fhost = (char *)hostname; + } else + hostres = gethostinfo(hostname, 1); for (res = hostres; res; res = res->ai_next) { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) @@ -353,6 +387,7 @@ } } } + if (fhost) free(fhost); if (nhost != NULL) { whois(query, nhost, 0); free(nhost); >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903302256.n2UMuYcs034597>