-.\" $OpenBSD: whois.1,v 1.32 2013/03/05 16:09:10 sthen Exp $
+.\" $OpenBSD: whois.1,v 1.33 2015/04/09 19:29:53 sthen Exp $
.\" $NetBSD: whois.1,v 1.5 1995/08/31 21:51:32 jtc Exp $
.\"
.\" Copyright (c) 1985, 1990, 1993
.\"
.\" @(#)whois.1 8.2 (Berkeley) 6/20/94
.\"
-.Dd $Mdocdate: March 5 2013 $
+.Dd $Mdocdate: April 9 2015 $
.Dt WHOIS 1
.Os
.Sh NAME
.Nm
constructs the name of a whois server to use from the top-level domain
.Pq Tn TLD
-of the supplied (single) argument, and appending
-.Qq Li .whois-servers.net .
+of the supplied (single) argument.
+For newer generic domains (gTLDs), a lookup for whois.nic.tld is attempted.
+For other TLDs, or if this lookup fails,
+.Qq Li .whois-servers.net
+is appended to the TLD.
This effectively allows a suitable whois server to be selected
automatically for a large number of
.Tn TLDs .
-/* $OpenBSD: whois.c,v 1.46 2014/01/03 15:25:18 millert Exp $ */
+/* $OpenBSD: whois.c,v 1.47 2015/04/09 19:29:53 sthen Exp $ */
/*
* Copyright (c) 1980, 1993
char *nserver;
char *ep;
size_t len;
+ struct addrinfo hints, *res;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = 0;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
if (country != NULL)
qhead = country;
if ((nserver = realloc(server, len)) == NULL)
err(1, "realloc");
server = nserver;
- strlcpy(server, qhead, len);
- strlcat(server, QNICHOST_TAIL, len);
+
+ /*
+ * Post-2003 ("new") gTLDs are all supposed to have "whois.nic.domain"
+ * (per registry agreement), some older gTLDs also support this...
+ */
+ strlcpy(server, "whois.nic.", len);
+ strlcat(server, qhead, len);
+
+ /* most ccTLDs don't do this, but QNICHOST/whois-servers mostly works */
+ if ((strlen(qhead) == 2 ||
+ /* and is required for most of the <=2003 TLDs/gTLDs */
+ strncasecmp(qhead, "org", 3) == 0 ||
+ strncasecmp(qhead, "com", 3) == 0 ||
+ strncasecmp(qhead, "net", 3) == 0 ||
+ strncasecmp(qhead, "cat", 3) == 0 ||
+ strncasecmp(qhead, "pro", 3) == 0 ||
+ strncasecmp(qhead, "info", 4) == 0 ||
+ strncasecmp(qhead, "aero", 4) == 0 ||
+ strncasecmp(qhead, "jobs", 4) == 0 ||
+ strncasecmp(qhead, "mobi", 4) == 0 ||
+ strncasecmp(qhead, "museum", 6) == 0 ||
+ /* for others, if whois.nic.TLD doesn't exist, try whois-servers */
+ getaddrinfo(server, NULL, &hints, &res) != 0)) {
+ strlcpy(server, qhead, len);
+ strlcat(server, QNICHOST_TAIL, len);
+ }
+
return (server);
}