bin/73801: [patch] allow whois(1) to choose source address

Edwin Groothuis edwin at mavetju.org
Wed Nov 10 19:00:42 PST 2004


>Number:         73801
>Category:       bin
>Synopsis:       [patch] allow whois(1) to choose source address
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 11 03:00:41 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Edwin Groothuis
>Release:        FreeBSD 5.2.1-RELEASE i386
>Organization:
-
>Environment:
System: FreeBSD k7.mavetju 5.2.1-RELEASE FreeBSD 5.2.1-RELEASE #7: Tue Sep 21 23:13:39 EST 2004 root at k7.mavetju:/usr/src-5.2.1/sys/i386/compile/k7 i386


>Description:

I'm responsible (it's only once per month, but still) to check the
data in the whois records for validity. But what happens if you
check more than 20 domains in the .au namespace:

    [~] edwin at k7>whois barnet.com.au
    BLACKLISTED: You have exceeded the query limit for your IP address and have been blacklisted. This restriction will be removed in 24 hours.

The Australian WHOIS Registry has set a limit to the number of
queries you are allowed to do from a single IP address per day.
This is a maximum of 100 per day, but it already cuts off if you
do more than 20 per hour.

So, for checking my list I need 8 hours (144 domains), and spread
over two days. Or I can use a different computer each time. Or a
different IP address (if whois(1) supported it)

This patch lets you set the source IP address for the outgoing TCP
session of the whois command.

>How-To-Repeat:
>Fix:

--- whois.1.old	Thu Nov 11 13:39:06 2004
+++ whois.1	Thu Nov 11 13:38:37 2004
@@ -43,6 +43,7 @@
 .Op Fl aAdgilmQrR6
 .Op Fl c Ar country-code | Fl h Ar host
 .Op Fl p Ar port
+.Op Fl S Ar src_addr
 .Ar name ...
 .Sh DESCRIPTION
 The
@@ -166,6 +167,10 @@
 If this option is not specified,
 .Nm
 defaults to port 43.
+.It Fl S Ar src_addr
+Set the source IP address for the TCP connection to 
+.Ar src_addr ,
+which can be an IP address or a host name.
 .It Fl Q
 Do a quick lookup.
 This means that
--- whois.c.old	Thu Nov 11 13:04:09 2004
+++ whois.c	Thu Nov 11 13:50:18 2004
@@ -84,6 +84,7 @@
 
 const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST, NULL };
 const char *port = DEFAULT_PORT;
+const char *src_addr = NULL;
 
 static char *choose_server(char *);
 static struct addrinfo *gethostinfo(char const *host, int exit_on_error);
@@ -104,7 +105,7 @@
 
 	country = host = qnichost = NULL;
 	flags = use_qnichost = 0;
-	while ((ch = getopt(argc, argv, "aAc:dgh:ilmp:QrR6")) != -1) {
+	while ((ch = getopt(argc, argv, "aAc:dgh:ilmp:QrRS:6")) != -1) {
 		switch (ch) {
 		case 'a':
 			host = ANICHOST;
@@ -146,6 +147,9 @@
 			warnx("-R is deprecated; use '-c ru' instead");
 			country = "ru";
 			break;
+		case 'S':
+			src_addr = optarg;
+			break;
 		case '6':
 			host = SNICHOST;
 			break;
@@ -261,16 +265,34 @@
 whois(const char *query, const char *hostname, int flags)
 {
 	FILE *sfi, *sfo;
-	struct addrinfo *hostres, *res;
+	struct addrinfo *hostres, *res, *src_res, *src_res0 = NULL;;
 	char *buf, *host, *nhost, *p;
 	int i, s;
 	size_t c, len;
 
+	/* Cache source addresses */
+	if (src_addr != NULL) {
+		src_res = gethostinfo(src_addr, 1);
+		src_res0 = src_res;
+	}
+
 	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;
+
+		/* Set source address if requested */
+		if (src_addr != NULL) {
+			for (src_res = src_res0; src_res != 0; src_res = src_res->ai_next)
+				if (src_res->ai_family == res->ai_family)
+					break;
+			if (src_res == NULL)
+				src_res = src_res0;
+			if (bind(s, src_res->ai_addr, src_res->ai_addrlen) == -1)
+				err(EX_OSERR, "bind() to %s",src_addr);
+		}
+
 		if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
 			break;
 		close(s);
@@ -339,6 +361,6 @@
 {
 	fprintf(stderr,
 	    "usage: whois [-aAdgilmQrR6] [-c country-code | -h hostname] "
-	    "[-p port] name ...\n");
+	    "[-p port] [-S src_addr] name ...\n");
 	exit(EX_USAGE);
 }
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list