From 236facc747f8dd17d8ca9d3dd156d5779c1e5f73 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 9 Jul 2012 23:08:29 -0400 Subject: [PATCH] whois (freebsd 8.1) http://www.opensource.apple.com/source/adv_cmds/adv_cmds-118/whois.tproj/ --- bin/whois/whois.1 | 278 +++++++++++++++++++++++++++++++++++ bin/whois/whois.c | 363 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 641 insertions(+) create mode 100644 bin/whois/whois.1 create mode 100644 bin/whois/whois.c diff --git a/bin/whois/whois.1 b/bin/whois/whois.1 new file mode 100644 index 0000000..943cdec --- /dev/null +++ b/bin/whois/whois.1 @@ -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 . diff --git a/bin/whois/whois.c b/bin/whois/whois.c new file mode 100644 index 0000000..1ee8959 --- /dev/null +++ b/bin/whois/whois.c @@ -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 +#ifndef __APPLE__ +__FBSDID("$FreeBSD: src/usr.bin/whois/whois.c,v 1.41 2004/08/25 15:34:44 mbr Exp $"); +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); +}