Kelvin Sherlock 2012-07-09 23:08:29 -04:00
parent 209804912e
commit 236facc747
2 changed files with 641 additions and 0 deletions

278
bin/whois/whois.1 Normal file
View File

@ -0,0 +1,278 @@
.\" Copyright (c) 1985, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" From: @(#)whois.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD: src/usr.bin/whois/whois.1,v 1.32 2004/06/14 17:30:46 bms Exp $
.\"
.Dd June 14, 2004
.Dt WHOIS 1
.Os
.Sh NAME
.Nm whois
.Nd "Internet domain name and network number directory service"
.Sh SYNOPSIS
.Nm
.Op Fl aAbdgiIlmQrR6
.Op Fl c Ar country-code | Fl h Ar host
.Op Fl p Ar port
.Ar name ...
.Sh DESCRIPTION
The
.Nm
utility looks up records in the databases maintained by several
Network Information Centers
.Pq Tn NICs .
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl 6
Use the IPv6 Resource Center
.Pq Tn 6bone
database.
It contains network names and addresses for the IPv6 network.
.It Fl A
Use the Asia/Pacific Network Information Center
.Pq Tn APNIC
database.
It contains network numbers used in East Asia, Australia,
New Zealand, and the Pacific islands.
.It Fl a
Use the American Registry for Internet Numbers
.Pq Tn ARIN
database.
It contains network numbers used in those parts of the world covered neither by
.Tn APNIC
nor by
.Tn RIPE .
.Pp
(Hint: All point of contact handles in the
.Tn ARIN
whois database end with
.Qq Li -ARIN . )
.Pp
.It Fl b
Use the Network Abuse Clearinghouse database.
It contains addresses to which network abuse should be reported,
indexed by domain name.
.It Fl c Ar country-code
This is the equivalent of using the
.Fl h
option with an argument of
.Qq Ar country-code Ns Li .whois-servers.net .
.It Fl d
Use the US Department of Defense
database.
It contains points of contact for subdomains of
.Pa .MIL .
.It Fl g
Use the US non-military federal government database, which contains points of
contact for subdomains of
.Pa .GOV .
.It Fl h Ar host
Use the specified host instead of the default variant.
Either a host name or an IP address may be specified.
.Pp
By default
.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 .
This effectively allows a suitable whois server to be selected
automatically for a large number of
.Tn TLDs .
.Pp
In the event that an IP
address 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 , LACNIC ,
or
.Tn RIPE ,
that server will be queried also, provided that the
.Fl Q
option is not specified.
.Pp
If the query is not a domain name or IP address,
.Nm
will fall back to
.Pa whois.crsnic.net .
.It Fl I
Use the Internet Assigned Numbers Authority
.Pq Tn IANA
database.
It contains network information for top-level domains.
.It Fl i
Use the Network Solutions Registry for Internet Numbers
.Pq Pa whois.networksolutions.com
database.
It contains network numbers and domain contact information for most of
.Pa .COM , .NET , .ORG
and
.Pa .EDU
domains.
.Pp
.Sy NOTE !
The registration of these domains is now done
by a number of independent and competing registrars.
This database holds no information on domains registered by organizations
other than Network Solutions, Inc.
Also, note that the
.Tn InterNIC
database
.Pq Pa whois.internic.net
is no longer handled by Network Solutions, Inc.
For details, see
.Pa http://www.internic.net/ .
.Pp
(Hint: Contact information, identified by the term
.Em handle ,
can be looked up by prefixing
.Qq Li "handle "
to the
.Tn NIC
handle in the query.)
.It Fl l
Use the Latin American and Caribbean IP address Regional Registry
.Pq Tn LACNIC
database.
It contains network numbers used in much of Latin America and the
Caribbean.
.It Fl m
Use the Route Arbiter Database
.Pq Tn RADB
database.
It contains route policy specifications for a large
number of operators' networks.
.It Fl p Ar port
Connect to the whois server on
.Ar port .
If this option is not specified,
.Nm
defaults to port 43.
.It Fl Q
Do a quick lookup.
This means that
.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.
.It Fl R
Use the Russia Network Information Center
.Pq Tn RIPN
database.
It contains network numbers and domain contact information
for subdomains of
.Pa .RU .
This option is deprecated; use the
.Fl c
option with an argument of
.Qq Li RU
instead.
.It Fl r
Use the R\(aaeseaux IP Europ\(aaeens
.Pq Tn RIPE
database.
It contains network numbers and domain contact information
for Europe.
.El
.Pp
The operands specified to
.Nm
are treated independently and may be used
as queries on different whois servers.
.Sh EXAMPLES
Most types of data, such as domain names and
.Tn IP
addresses, can be used as arguments to
.Nm
without any options, and
.Nm
will choose the correct whois server to query.
Some exceptions, where
.Nm
will not be able to handle data correctly, are detailed below.
.Pp
To obtain contact information about an
administrator located in the Russian
.Tn TLD
domain
.Qq Li RU ,
use the
.Fl c
option as shown in the following example, where
.Ar CONTACT-ID
is substituted with the actual contact identifier.
.Pp
.Dl "whois -c RU CONTACT-ID"
.Pp
(Note: This example is specific to the
.Tn TLD
.Qq Li RU ,
but other
.Tn TLDs
can be queried by using a similar syntax.)
.Pp
The following example demonstrates how to obtain information about an
.Tn IPv6
address or hostname using the
.Fl 6
option, which directs the query to
.Tn 6bone .
.Pp
.Dl "whois -6 IPv6-IP-Address"
.Pp
The following example demonstrates how to query
a whois server using a non-standard port, where
.Dq Li query-data
is the query to be sent to
.Dq Li whois.example.com
on port
.Dq Li rwhois
(written numerically as 4321).
.Pp
.Dl "whois -h whois.example.com -p rwhois query-data"
.Sh SEE ALSO
.Rs
.%A Ken Harrenstien
.%A Vic White
.%T NICNAME/WHOIS
.%D 1 March 1982
.%O RFC 812
.Re
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.3 .

363
bin/whois/whois.c Normal file
View File

@ -0,0 +1,363 @@
/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1980, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#if 0
#ifndef lint
static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
#ifndef __APPLE__
__FBSDID("$FreeBSD: src/usr.bin/whois/whois.c,v 1.41 2004/08/25 15:34:44 mbr Exp $");
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#define ABUSEHOST "whois.abuse.net"
#define NICHOST "whois.crsnic.net"
#define INICHOST "whois.networksolutions.com"
#define DNICHOST "whois.nic.mil"
#define GNICHOST "whois.nic.gov"
#define ANICHOST "whois.arin.net"
#define LNICHOST "whois.lacnic.net"
#define RNICHOST "whois.ripe.net"
#define PNICHOST "whois.apnic.net"
#define MNICHOST "whois.ra.net"
#define QNICHOST_TAIL ".whois-servers.net"
#define SNICHOST "whois.6bone.net"
#define BNICHOST "whois.registro.br"
#define NORIDHOST "whois.norid.no"
#define IANAHOST "whois.iana.org"
#define GERMNICHOST "de.whois-servers.net"
#define DEFAULT_PORT "nicname"
#define WHOIS_SERVER_ID "Whois Server: "
#define WHOIS_ORG_SERVER_ID "Registrant Street1:Whois Server:"
#define WHOIS_RECURSE 0x01
#define WHOIS_QUICK 0x02
#define ishost(h) (isalnum((unsigned char)h) || h == '.' || h == '-')
const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST, NULL };
const char *port = DEFAULT_PORT;
static char *choose_server(char *);
static struct addrinfo *gethostinfo(char const *host, int exit_on_error);
#ifdef __APPLE__
static void s_asprintf(char **ret, const char *format, ...) __attribute__((__format__(printf, 2, 3)));
#else
static void s_asprintf(char **ret, const char *format, ...) __printflike(2, 3);
#endif
static void usage(void);
static void whois(const char *, const char *, int);
int
main(int argc, char *argv[])
{
const char *country, *host;
char *qnichost;
int ch, flags, use_qnichost;
#ifdef SOCKS
SOCKSinit(argv[0]);
#endif
country = host = qnichost = NULL;
flags = use_qnichost = 0;
while ((ch = getopt(argc, argv, "aAbc:dgh:iIlmp:QrR6")) != -1) {
switch (ch) {
case 'a':
host = ANICHOST;
break;
case 'A':
host = PNICHOST;
break;
case 'b':
host = ABUSEHOST;
break;
case 'c':
country = optarg;
break;
case 'd':
host = DNICHOST;
break;
case 'g':
host = GNICHOST;
break;
case 'h':
host = optarg;
break;
case 'i':
host = INICHOST;
break;
case 'I':
host = IANAHOST;
break;
case 'l':
host = LNICHOST;
break;
case 'm':
host = MNICHOST;
break;
case 'p':
port = optarg;
break;
case 'Q':
flags |= WHOIS_QUICK;
break;
case 'r':
host = RNICHOST;
break;
case 'R':
warnx("-R is deprecated; use '-c ru' instead");
country = "ru";
break;
case '6':
host = SNICHOST;
break;
case '?':
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (!argc || (country != NULL && host != NULL))
usage();
/*
* If no host or country is specified determine the top level domain
* from the query. If the TLD is a number, query ARIN. Otherwise, use
* TLD.whois-server.net. If the domain does not contain '.', fall
* back to NICHOST.
*/
if (host == NULL && country == NULL) {
use_qnichost = 1;
host = NICHOST;
if (!(flags & WHOIS_QUICK))
flags |= WHOIS_RECURSE;
}
while (argc-- > 0) {
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)
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.
*/
static char *
choose_server(char *domain)
{
char *pos, *retval;
for (pos = strchr(domain, '\0'); pos > domain && *--pos == '.';)
*pos = '\0';
if (*domain == '\0')
errx(EX_USAGE, "can't search for a null string");
if (strlen(domain) > sizeof("-NORID")-1 &&
strcasecmp(domain + strlen(domain) - sizeof("-NORID") + 1,
"-NORID") == 0) {
s_asprintf(&retval, "%s", NORIDHOST);
return (retval);
}
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);
}
static struct addrinfo *
gethostinfo(char const *host, int exit_on_error)
{
struct addrinfo hints, *res;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = 0;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(host, port, &hints, &res);
if (error) {
warnx("%s: %s", host, gai_strerror(error));
if (exit_on_error)
exit(EX_NOHOST);
return (NULL);
}
return (res);
}
/*
* Wrapper for asprintf(3) that exits on error.
*/
static void
s_asprintf(char **ret, const char *format, ...)
{
va_list ap;
va_start(ap, format);
if (vasprintf(ret, format, ap) == -1) {
va_end(ap);
err(EX_OSERR, "vasprintf()");
}
va_end(ap);
}
static void
whois(const char *query, const char *hostname, int flags)
{
FILE *sfi, *sfo;
struct addrinfo *hostres, *res;
char *buf, *host, *nhost, *p;
int i, s;
size_t c, len;
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)
continue;
if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
break;
close(s);
}
freeaddrinfo(hostres);
if (res == NULL)
err(EX_OSERR, "connect()");
sfi = fdopen(s, "r");
sfo = fdopen(s, "w");
if (sfi == NULL || sfo == NULL)
err(EX_OSERR, "fdopen()");
if (strcmp(hostname, GERMNICHOST) == 0) {
fprintf(sfo, "-T dn,ace -C US-ASCII %s\r\n", query);
} else {
fprintf(sfo, "%s\r\n", query);
}
fflush(sfo);
nhost = NULL;
while ((buf = fgetln(sfi, &len)) != NULL) {
while (len > 0 && isspace((unsigned char)buf[len - 1]))
buf[--len] = '\0';
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';
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((int)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;
}
}
}
}
}
if (nhost != NULL) {
whois(query, nhost, 0);
free(nhost);
}
}
static void
usage(void)
{
fprintf(stderr,
"usage: whois [-aAbdgiIlmQrR6] [-c country-code | -h hostname] "
"[-p port] name ...\n");
exit(EX_USAGE);
}