diff options
author | Tony Finch <fanf@FreeBSD.org> | 2016-11-17 15:19:06 +0000 |
---|---|---|
committer | Tony Finch <fanf@FreeBSD.org> | 2016-11-17 15:19:06 +0000 |
commit | 3997df0cde8f5e4f4b5fcc21b5530b900e9fd851 (patch) | |
tree | 3537668070649409b5fafcbb1e567d6a5937deeb /usr.bin/whois | |
parent | ead1785e1e9cca686d4914cfb8dd519ab1d17677 (diff) | |
download | src-3997df0cde8f5e4f4b5fcc21b5530b900e9fd851.tar.gz src-3997df0cde8f5e4f4b5fcc21b5530b900e9fd851.zip |
Notes
Diffstat (limited to 'usr.bin/whois')
-rw-r--r-- | usr.bin/whois/whois.c | 79 |
1 files changed, 75 insertions, 4 deletions
diff --git a/usr.bin/whois/whois.c b/usr.bin/whois/whois.c index 4f4062b7c7f1..de3b946def40 100644 --- a/usr.bin/whois/whois.c +++ b/usr.bin/whois/whois.c @@ -119,12 +119,38 @@ static struct { { NULL, 0 } }; +/* + * We have a list of patterns for RIRs that assert ignorance rather than + * providing referrals. If that happens, we guess that ARIN will be more + * helpful. But, before following a referral to an RIR, we check if we have + * asked that RIR already, and if so we make another guess. + */ static const char *actually_arin[] = { "netname: ERX-NETBLOCK\n", /* APNIC */ "netname: NON-RIPE-NCC-MANAGED-ADDRESS-BLOCK\n", NULL }; +static struct { + int loop; + const char *host; +} try_rir[] = { + { 0, ANICHOST }, + { 0, RNICHOST }, + { 0, PNICHOST }, + { 0, FNICHOST }, + { 0, LNICHOST }, + { 0, NULL } +}; + +static void +reset_rir(void) { + int i; + + for (i = 0; try_rir[i].host != NULL; i++) + try_rir[i].loop = 0; +} + static const char *port = DEFAULT_PORT; static const char *choose_server(char *); @@ -232,6 +258,7 @@ main(int argc, char *argv[]) } else whois(*argv, host != NULL ? host : choose_server(*argv), flags); + reset_rir(); argv++; } exit(0); @@ -420,7 +447,7 @@ whois(const char *query, const char *hostname, int flags) FILE *fp; struct addrinfo *hostres; char *buf, *host, *nhost, *p; - int s, f; + int comment, s, f; size_t len, i; hostres = gethostinfo(hostname, 1); @@ -467,12 +494,28 @@ whois(const char *query, const char *hostname, int flags) fprintf(fp, "%s\r\n", query); fflush(fp); + comment = 0; + if (!(flags & WHOIS_SPAM_ME) && + (strcasecmp(hostname, ANICHOST) == 0 || + strcasecmp(hostname, RNICHOST) == 0)) { + comment = 2; + } + nhost = NULL; while ((buf = fgetln(fp, &len)) != NULL) { /* Nominet */ if (!(flags & WHOIS_SPAM_ME) && len == 5 && strncmp(buf, "-- \r\n", 5) == 0) break; + /* RIRs */ + if (comment == 1 && buf[0] == '#') + break; + else if (comment == 2) { + if (strchr("#%\r\n", buf[0]) != NULL) + continue; + else + comment = 1; + } printf("%.*s", (int)len, buf); @@ -487,8 +530,7 @@ whois(const char *query, const char *hostname, int flags) SCAN(p, buf+len, *p == ' '); host = p; SCAN(p, buf+len, ishost(*p)); - /* avoid loops */ - if (strncmp(hostname, host, p - host) != 0) + if (p > host) s_asprintf(&nhost, "%.*s", (int)(p - host), host); break; @@ -511,8 +553,37 @@ whois(const char *query, const char *hostname, int flags) } fclose(fp); freeaddrinfo(hostres); + + f = 0; + for (i = 0; try_rir[i].host != NULL; i++) { + /* Remember visits to RIRs */ + if (try_rir[i].loop == 0 && + strcasecmp(try_rir[i].host, hostname) == 0) + try_rir[i].loop = 1; + /* Do we need to find an alternative RIR? */ + if (try_rir[i].loop != 0 && nhost != NULL && + strcasecmp(try_rir[i].host, nhost) == 0) { + free(nhost); + nhost = NULL; + f = 1; + } + } + if (f) { + /* Find a replacement RIR */ + for (i = 0; try_rir[i].host != NULL; i++) { + if (try_rir[i].loop == 0) { + s_asprintf(&nhost, "%s", + try_rir[i].host); + break; + } + } + } if (nhost != NULL) { - whois(query, nhost, flags); + /* Ignore self-referrals */ + if (strcasecmp(hostname, nhost) != 0) { + printf("# %s\n\n", nhost); + whois(query, nhost, flags); + } free(nhost); } } |