summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.bin/whois/whois.146
-rw-r--r--usr.bin/whois/whois.c90
2 files changed, 80 insertions, 56 deletions
diff --git a/usr.bin/whois/whois.1 b/usr.bin/whois/whois.1
index a9ed50a..a154f4a 100644
--- a/usr.bin/whois/whois.1
+++ b/usr.bin/whois/whois.1
@@ -59,18 +59,10 @@ and
.Qq Li whois.nic. Ns Va TLD
and if neither host exists it falls back to its default server.
.Pp
-If an IP address is specified, the whois server will default to
+If an IP address or AS number is specified,
+the whois server will default to
the American Registry for Internet Numbers
.Pq Tn ARIN .
-If a query to
-.Tn ARIN
-references
-.Tn APNIC , AfriNIC , LACNIC ,
-or
-.Tn RIPE ,
-that server will be queried also, provided that the
-.Fl Q
-option is not specified.
.Pp
If
.Nm
@@ -164,18 +156,42 @@ Use the PeeringDB database of AS numbers.
It contains details about presence at internet peering points
for many network operators.
.It Fl Q
-Do a quick lookup.
-This means that
+Do a quick lookup;
.Nm
-will not attempt to lookup the name in the authoritative whois
-server (if one is listed).
-This option has no effect when combined with any other options.
+will not attempt to follow referrals to other whois servers.
+This is the default if a server is explicitly specified
+using one of the other options.
+See also the
+.Fl R
+option.
.It Fl r
Use the R\(aaeseaux IP Europ\(aaeens
.Pq Tn RIPE
database.
It contains network numbers and domain contact information
for Europe.
+.It Fl R
+Do a recursive lookup;
+.Nm
+will attempt to follow referrals to other whois servers.
+This is the default if no server is explicitly specified.
+See also the
+.Fl Q
+option.
+.It Fl S
+By default, if the whois server is
+.Pa whois.verisign-grs.com
+(or a CNAME alias pointing at that name)
+then
+.Nm
+will query for
+.Dl domain Ar name
+The
+.Fl S
+option suppresses this behaviour,
+allowing you to make a loose-matching query,
+or query for host objects using the syntax
+.Dl nameserver Ar name
.El
.Pp
The operands specified to
diff --git a/usr.bin/whois/whois.c b/usr.bin/whois/whois.c
index 278b50c..2cb7f32 100644
--- a/usr.bin/whois/whois.c
+++ b/usr.bin/whois/whois.c
@@ -63,7 +63,7 @@ __FBSDID("$FreeBSD$");
#define ANICHOST "whois.arin.net"
#define BNICHOST "whois.registro.br"
#define FNICHOST "whois.afrinic.net"
-#define GERMNICHOST "de.whois-servers.net"
+#define GERMNICHOST "de" QNICHOST_TAIL
#define GNICHOST "whois.nic.gov"
#define IANAHOST "whois.iana.org"
#define INICHOST "whois.networksolutions.com"
@@ -76,14 +76,13 @@ __FBSDID("$FreeBSD$");
#define QNICHOST_HEAD "whois.nic."
#define QNICHOST_TAIL ".whois-servers.net"
#define RNICHOST "whois.ripe.net"
+#define VNICHOST "whois.verisign-grs.com"
#define DEFAULT_PORT "whois"
-#define WHOIS_SERVER_ID "Whois Server: "
-#define WHOIS_ORG_SERVER_ID "Registrant Street1:Whois Server:"
-
#define WHOIS_RECURSE 0x01
#define WHOIS_QUICK 0x02
+#define WHOIS_SPAM_ME 0x04
#define ishost(h) (isalnum((unsigned char)h) || h == '.' || h == '-')
@@ -100,8 +99,20 @@ static struct {
{ NULL, NULL }
};
-static const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST,
- FNICHOST, NULL };
+#define WHOIS_REFERRAL(s) { s, sizeof(s) - 1 }
+static struct {
+ const char *prefix;
+ size_t len;
+} whois_referral[] = {
+ WHOIS_REFERRAL("Whois Server: "),
+ WHOIS_REFERRAL("WHOIS Server: "),
+ WHOIS_REFERRAL(" Whois Server: "),
+ WHOIS_REFERRAL("refer: "),
+ WHOIS_REFERRAL("Registrant Street1:Whois Server:"),
+ WHOIS_REFERRAL("ReferralServer: whois://"),
+ { NULL, 0 }
+};
+
static const char *port = DEFAULT_PORT;
static char *choose_server(char *);
@@ -123,7 +134,7 @@ main(int argc, char *argv[])
country = host = qnichost = NULL;
flags = use_qnichost = 0;
- while ((ch = getopt(argc, argv, "aAbc:fgh:iIklmp:PQr")) != -1) {
+ while ((ch = getopt(argc, argv, "aAbc:fgh:iIklmp:PQrRS")) != -1) {
switch (ch) {
case 'a':
host = ANICHOST;
@@ -173,6 +184,12 @@ main(int argc, char *argv[])
case 'r':
host = RNICHOST;
break;
+ case 'R':
+ flags |= WHOIS_RECURSE;
+ break;
+ case 'S':
+ flags |= WHOIS_SPAM_ME;
+ break;
case '?':
default:
usage();
@@ -235,6 +252,13 @@ choose_server(char *domain)
s_asprintf(&retval, "%s", ANICHOST);
return (retval);
}
+ if (strncasecmp(domain, "AS", 2) == 0) {
+ size_t len = strspn(domain + 2, "0123456789");
+ if (domain[len + 2] == '\0') {
+ s_asprintf(&retval, "%s", ANICHOST);
+ return (retval);
+ }
+ }
for (pos = strchr(domain, '\0'); pos > domain && pos[-1] == '.';)
*--pos = '\0';
if (*domain == '\0')
@@ -285,7 +309,7 @@ gethostinfo(char const *host, int exit_on_noname)
int error;
memset(&hints, 0, sizeof(hints));
- hints.ai_flags = 0;
+ hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
res = NULL;
@@ -317,9 +341,9 @@ whois(const char *query, const char *hostname, int flags)
FILE *fp;
struct addrinfo *hostres, *res;
char *buf, *host, *nhost, *p;
- int s = -1, f;
+ int s = -1, f, antispam;
nfds_t i, j;
- size_t c, len, count;
+ size_t len, count;
struct pollfd *fds;
int timeout = 180;
@@ -327,6 +351,9 @@ whois(const char *query, const char *hostname, int flags)
for (res = hostres, count = 0; res; res = res->ai_next)
count++;
+ antispam = (flags & WHOIS_SPAM_ME) == 0 &&
+ strcmp(hostres->ai_canonname, VNICHOST) == 0;
+
fds = calloc(count, sizeof(*fds));
if (fds == NULL)
err(EX_OSERR, "calloc()");
@@ -457,6 +484,8 @@ done:
fprintf(fp, "-T dn,ace -C ISO-8859-1 %s\r\n", query);
} else if (strcmp(hostname, "dk" QNICHOST_TAIL) == 0) {
fprintf(fp, "--show-handles %s\r\n", query);
+ } else if (antispam) {
+ fprintf(fp, "domain %s\r\n", query);
} else {
fprintf(fp, "%s\r\n", query);
}
@@ -468,39 +497,18 @@ done:
printf("%.*s\n", (int)len, buf);
if ((flags & WHOIS_RECURSE) && nhost == NULL) {
- host = strnstr(buf, WHOIS_SERVER_ID, len);
- if (host != NULL) {
- host += sizeof(WHOIS_SERVER_ID) - 1;
- for (p = host; p < buf + len; p++) {
- if (!ishost(*p)) {
- *p = '\0';
+ for (i = 0; whois_referral[i].prefix != NULL; i++) {
+ if (strncmp(buf,
+ whois_referral[i].prefix,
+ whois_referral[i].len) != 0)
+ continue;
+ host = buf + whois_referral[i].len;
+ for (p = host; p < buf + len; p++)
+ if (!ishost(*p))
break;
- }
- }
s_asprintf(&nhost, "%.*s",
- (int)(buf + len - host), host);
- } else if ((host =
- strnstr(buf, WHOIS_ORG_SERVER_ID, len)) != NULL) {
- host += sizeof(WHOIS_ORG_SERVER_ID) - 1;
- for (p = host; p < buf + len; p++) {
- if (!ishost(*p)) {
- *p = '\0';
- break;
- }
- }
- s_asprintf(&nhost, "%.*s",
- (int)(buf + len - host), host);
- } else if (strcmp(hostname, ANICHOST) == 0) {
- for (c = 0; c <= len; c++)
- buf[c] = tolower((unsigned char)buf[c]);
- for (i = 0; ip_whois[i] != NULL; i++) {
- if (strnstr(buf, ip_whois[i], len) !=
- NULL) {
- s_asprintf(&nhost, "%s",
- ip_whois[i]);
- break;
- }
- }
+ (int)(p - host), host);
+ break;
}
}
}
OpenPOWER on IntegriCloud