aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/whois
diff options
context:
space:
mode:
authorTony Finch <fanf@FreeBSD.org>2016-11-17 15:19:06 +0000
committerTony Finch <fanf@FreeBSD.org>2016-11-17 15:19:06 +0000
commit3997df0cde8f5e4f4b5fcc21b5530b900e9fd851 (patch)
tree3537668070649409b5fafcbb1e567d6a5937deeb /usr.bin/whois
parentead1785e1e9cca686d4914cfb8dd519ab1d17677 (diff)
downloadsrc-3997df0cde8f5e4f4b5fcc21b5530b900e9fd851.tar.gz
src-3997df0cde8f5e4f4b5fcc21b5530b900e9fd851.zip
Notes
Diffstat (limited to 'usr.bin/whois')
-rw-r--r--usr.bin/whois/whois.c79
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);
}
}