1 /* $NetBSD: whois.c,v 1.36 2013/02/20 09:27:52 ws Exp $ */
2 /* $OpenBSD: whois.c,v 1.28 2003/09/18 22:16:15 fgsch Exp $ */
5 * Copyright (c) 1980, 1993
6 * The Regents of the University of California. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
36 __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
37 The Regents of the University of California. All rights reserved.");
42 static const char sccsid
[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93";
44 __RCSID("$NetBSD: whois.c,v 1.36 2013/02/20 09:27:52 ws Exp $");
48 #include <sys/types.h>
49 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
63 #define ANICHOST "whois.arin.net"
64 #define BNICHOST "whois.registro.br"
65 #define CNICHOST "whois.corenic.net"
66 #define DNICHOST "whois.nic.mil"
67 #define FNICHOST "whois.afrinic.net"
68 #define GNICHOST "whois.nic.gov"
69 #define INICHOST "whois.networksolutions.com"
70 #define LNICHOST "whois.lacnic.net"
71 #define MNICHOST "whois.ra.net"
72 #define NICHOST "whois.crsnic.net"
73 #define PNICHOST "whois.apnic.net"
74 #define QNICHOST_TAIL ".whois-servers.net"
75 #define RNICHOST "whois.ripe.net"
76 #define RUNICHOST "whois.ripn.net"
77 #define SNICHOST "whois.6bone.net"
79 #define WHOIS_PORT "whois"
80 #define WHOIS_SERVER_ID "Whois Server:"
82 #define WHOIS_RECURSE 0x01
83 #define WHOIS_QUICK 0x02
85 static const char *port_whois
= WHOIS_PORT
;
86 static const char *ip_whois
[] =
87 { LNICHOST
, RNICHOST
, PNICHOST
, FNICHOST
, BNICHOST
, NULL
};
89 static void usage(void) __dead
;
90 static int whois(const char *, const char *, const char *, int);
91 static const char *choose_server(const char *, const char *);
94 main(int argc
, char *argv
[])
97 const char *host
, *name
, *country
;
102 country
= host
= NULL
;
104 while ((ch
= getopt(argc
, argv
, "6Aac:dfgh:ilmp:qQRr")) != -1)
140 /* deprecated, now the default */
143 flags
|= WHOIS_QUICK
;
160 if (!argc
|| (country
!= NULL
&& host
!= NULL
))
163 if (host
== NULL
&& country
== NULL
&& !(flags
& WHOIS_QUICK
))
164 flags
|= WHOIS_RECURSE
;
165 for (name
= *argv
; (name
= *argv
) != NULL
; argv
++)
166 rval
+= whois(name
, host
? host
: choose_server(name
, country
),
172 whois(const char *query
, const char *server
, const char *port
, int flags
)
175 char *buf
, *p
, *nhost
, *nbuf
= NULL
;
178 const char *reason
= NULL
, *fmt
;
179 struct addrinfo hints
, *res
, *ai
;
181 (void)memset(&hints
, 0, sizeof(hints
));
183 hints
.ai_family
= AF_UNSPEC
;
184 hints
.ai_socktype
= SOCK_STREAM
;
185 error
= getaddrinfo(server
, port
, &hints
, &res
);
187 warnx("%s: %s", server
, gai_strerror(error
));
191 for (s
= -1, ai
= res
; ai
!= NULL
; ai
= ai
->ai_next
) {
192 s
= socket(ai
->ai_family
, ai
->ai_socktype
, ai
->ai_protocol
);
198 if (connect(s
, ai
->ai_addr
, ai
->ai_addrlen
) < 0) {
210 warn("%s: %s", server
, reason
);
212 warnx("Unknown error in connection attempt");
217 if (strcmp(server
, "whois.denic.de") == 0 ||
218 strcmp(server
, "de.whois-servers.net") == 0)
219 fmt
= "-T dn,ace -C ISO-8859-1 ";
223 sfi
= fdopen(s
, "r");
224 sfo
= fdopen(s
, "w");
225 if (sfi
== NULL
|| sfo
== NULL
)
227 (void)fprintf(sfo
, "%s%s\r\n", fmt
, query
);
230 while ((buf
= fgetln(sfi
, &len
)) != NULL
) {
232 if (isspace((unsigned char)*p
)) {
235 while (p
> buf
&& isspace((unsigned char)*--p
));
237 if ((nbuf
= malloc(len
+ 1)) == NULL
)
239 (void)memcpy(nbuf
, buf
, len
);
245 if (nhost
!= NULL
|| !(flags
& WHOIS_RECURSE
))
248 if ((p
= strstr(buf
, WHOIS_SERVER_ID
))) {
249 p
+= sizeof(WHOIS_SERVER_ID
) - 1;
250 while (isblank((unsigned char)*p
))
252 if ((len
= strcspn(p
, " \t\n\r"))) {
253 if ((nhost
= malloc(len
+ 1)) == NULL
)
255 (void)memcpy(nhost
, p
, len
);
258 } else if (strcmp(server
, ANICHOST
) == 0) {
259 for (p
= buf
; *p
!= '\0'; p
++)
260 *p
= tolower((unsigned char)*p
);
261 for (i
= 0; ip_whois
[i
] != NULL
; i
++) {
262 if (strstr(buf
, ip_whois
[i
]) != NULL
) {
263 nhost
= strdup(ip_whois
[i
]);
275 error
= whois(query
, nhost
, port
, 0);
285 * If no country is specified determine the top level domain from the query.
286 * If the TLD is a number, query ARIN, otherwise, use TLD.whois-server.net.
287 * If the domain does not contain '.', check to see if it is an NSI handle
288 * (starts with '!') or a CORE handle (COCO-[0-9]+ or COHO-[0-9]+).
289 * Fall back to NICHOST for the non-handle case.
292 choose_server(const char *name
, const char *country
)
302 else if ((qhead
= strrchr(name
, '.')) == NULL
) {
305 else if ((strncasecmp(name
, "COCO-", 5) == 0 ||
306 strncasecmp(name
, "COHO-", 5) == 0) &&
307 strtol(name
+ 5, &ep
, 10) > 0 && *ep
== '\0')
311 } else if (isdigit((unsigned char)*(++qhead
)))
313 len
= strlen(qhead
) + sizeof(QNICHOST_TAIL
);
314 if ((nserver
= realloc(server
, len
)) == NULL
)
317 (void)strlcpy(server
, qhead
, len
);
318 (void)strlcat(server
, QNICHOST_TAIL
, len
);
325 (void)fprintf(stderr
,
326 "usage: %s [-6AadgilmQRr] [-c country-code | -h hostname] "
327 "[-p port] name ...\n", getprogname());