'.
DATABASE SUPPORT
As of version 0.5, jdresolve provides simple database support thru db
(dbm, gdbm, sdbm, etc) files. You can use the --database switch to
specify the db file and that will allow for fallback in case some DNS
servers are down and also performance improvements since you can lower
your timeout value without sacrificing resolved percentage.
To use the database support, just supply a database name (i.e.
'hosts.db') using the --database option. If it does not yet exist, a
new database with that name will be created. All resolved hosts and
classes during a jdresolve run will be cached to the database.
After you have some data in a db, you can use --dumpdb to look at it.
With --mergedb to add new information to it (the format of the input
file is the same as the one from a dump using --dumpdb, e.g. an
ip/class followed by the hostname/classname, separated by white space)
Ex: echo "0.0.0.0 testip" | jdresolve --database hosts.db --mergedb -
...adds and IP entry to the db
Ex: echo "0.0.0 classname" | jdresolve --database hosts.db --mergedb -
...adds a class entry to the db
Note: Since when recursing the resolved hostnames are stored to the
database (even when resolved by recursion), you _may_ not want to use
the same database for normal and recursed runs. That is because a
cached host from a resolved run will show up as a "real" IP if you
don't recurse and use the --dbfirst or --dbonly options, or just use
the database and the lookup times out. Nothing too serious, but this
detail may be important to some people.
SOME NOTES ON NET::DNS
It seems that Net::DNS can perform suboptimally on non-Linux machines,
even on *BSD (this is based on some bug reports I got from people
using jdresolve in those environments). Also, on Windows NT (yes, some
people still use that), you should make sure there is a 'resolv.conf'
file somewhere (I'm no NT expert, read the docs). Since we use so
little of the functionality of Net::DNS, I may replace it with
standard sockets some time in the future. It is still a very very nice
module though :)
SUPPORT
If you have dificulties using this program or would like to request a
new feature, feel free to reach me at me@jdrowell.com.
LICENSING
jdresolve is licensed under the GPL. See the COPYING file for details.
References
1. mailto:me@jdrowell.com
2. http://www.jdrowell.com/Linux/Projects/jdresolve
3. http://www.cpan.org/
jdresolve-0.6.1.orig/README.html 0100644 0001750 0000144 00000023662 07126534202 015333 0 ustar mvela users
Application: jdresolve 0.6.1
Author: John D. Rowell
Homepage: http://www.jdrowell.com/Linux/Projects/jdresolve
FOR THE IMPATIENT
./configure
make install
Try: jdresolve <log file> > <resolved file>
i.e. jdresolve access_log > resolved.log
To use recursion, just use the "-r" command line option.
DESCRIPTION
jdresolve resolves IP addresses to hostnames. Any file format is supported, including those where the line does not begin with the IP address. One of the strongest features of the program is the support for recursion, which can drastically reduce the number of unresolved hosts by faking a hostname based on the network that the IP belongs to. DNS queries are sent in parallel, which means that you can decrease run time by increasing the number of simultaneous sockets used (given a fast enough machine and available bandwidth). By using the database support, performance can be increased even further, by using cached data from previous runs.
HOW IT USED TO WORK
jdresolve used the algorithms describe below up to version 0.2.
The initial version of jdresolve tried to only speed up the name resolution by implementing numerous concurrent requests. I The first problem was: how to resolve the maximum possible number of IPs concurrently without reading the whole log file into memory (they can get quite _huge_)? I figured I'd need a 2 pass approach, collecting all distinct host IPs that needing resolving in the first step, then resolving them efficiently inside a loop, and finally just replacing the resolved IPs on the second pass through the log file.
This way we can garantee that the resolve queue will always be full with no need to weight that against how many lines of buffered log entries we would need to cache. The number of distinct IP addresses tend to be quite lower than the number of lines in the log file, and the IP part takes about only 1/20th of the log line, so we can't be using too much memory just by putting a few hundred or thousand small strings into a hash.
After looking thru CPAN, I came across the excellent Net::DNS module and was more than happy to note that it already provide a subroutine and examples for background queries. Just add IO::Select to that and you have a full non-blocking aproach to multiple concurrent queries. You can even specify the timeouts to make the name resolving even more efficient.
Having this much done, I was quite happy to have the fastest log resolving routine I have come accross. By setting the numbers of concurrent sockets and timeouts you could fine tune the beast to resolve names _very_ rapidly. But still there where about 25% of the IPs left unresolved...
"This is not much help", I thought. I need to know _at least_ from what country these people are accessing from. After a few not very scientifical aproaches, I realized that by recurring thru the DNS classes (C, B and finally A) and checking for the host listed in the SOA record I could be pretty sure this was a father domain to the IP. The implementation goes like this: find out all distinct IP addresses, then determine which C, B and A classes contain these addresses. Make up a list from these queries and send them thru a resolver in chuncks of 32 (configurable via the command line). If a socket times out, leave that request unresolved.
After running a big log file against the recursive aproach, I determined it didn't take much longer to resolve it at all. Full class domains tend to have decently configured DNS servers, and you get a lot of repeated classes when resolving your logs. The best was still to come: 0 unresolved IPs :) And since that I haven't found an IP that can't be determined at least to it's A class.
HOW IT WORKS NOW
The above algorithm works extremely well except for the case of very large logs (>100Mb). The hashes containing IPs and their parent A/B/C classes gets pretty huge doesn't fit in memory any more.
So as of v0.3, we have a new 1 pass approach. We have a line cache that holds 10000 lines (configurable with -l, don't set it much lower). Using my test base it looks like each 10000 lines take about 4Mb of RAM during processing (that's the log lines themselves plus the hashes and arrays used for caching/processing). Each IP and class to be resolved has a count value, which is increased every time a line with that number is read, and decreased after we print out a resolved line with that reference value.
Think of it as a "moving window" method, and that we do our own garbage collection. The process pauses if the first line in our line cache is still unresolved, we don't have any more sockets, or we're waiting for socket data. We can't control the last two items, but to minimize the pauses do to yet unresolved lines, increase the -l value if you notice pauses during resolving. There should be enough lines cached so that even if we have timeouts on sockets we are still waiting for other socket data to come in, not just for 1 single socket to time out.
Using this method the memory usage during executing is almost constant. So you can determine how much RAM you wish to use for resolving names and set your -l value and forget about it. There's really no performance loss when compared to the <=v0.2 algorithm if you have a big enough line cache.
HOW TO USE IT
Example: jdresolve access_log > resolved.log
If you simply run the script as you would with the Apache logresolve program, you get the same results, only much faster. But if you want really take advantage of jdresolve, you should at least turn on the -r option for recursive resolves. As of version 0.2, the -m option takes a mask as an argument. The valid substitutions are %i for the IP address and %c for the resolved class. So an IP like 1.2.3.4 with a mask of "%i.%c" (the default) would become something like "1.2.3.4.some.domain". A mask of "somewhere.in.%c" would turn it into "somewhere.in.some.domain".
The -h switch shows you basic help information. The -v switch will display version information. Use -d 1 or -d 2 (more verbose) to debug the resolving process and get extra statistics. If you don't care for the default statistics, use -n to disable them.
After some runs you may want to change your timeout value. The -t option accepts a new value in seconds. For even better performance, use the -s switch with a value greater then 32, but remember that many operating systems have a hard coded default for open files of 256 or 1024. Check your system's limit with "ulimit -a".
New in v0.3 is the -l switch, which specified how many lines we will cache for resolving. The default is 10000, but can be vastly incremented without using too much RAM, as explained in "HOW IT WORKS".
After you used jdresolve on the log file, you can check which ips where left unresolved by using the --unresolved option on the file that was generated.
WHAT DOES RHOST DO?
'rhost' is a quick script to take advantage of the new STDIN functionality of jdresolve. Many times you use the 'host' command to resolve a single IP (like 'host 200.246.224.10'). As with standard log resolvers, 'host' doesn't do recursion. So 'rhost' just calls jdresolve with the apropriate parameters to resolve that single IP number. The syntax is 'rhost <ip>'.
DATABASE SUPPORT
As of version 0.5, jdresolve provides simple database support thru db (dbm, gdbm, sdbm, etc) files. You can use the --database switch to specify the db file and that will allow for fallback in case some DNS servers are down and also performance improvements since you can lower your timeout value without sacrificing resolved percentage.
To use the database support, just supply a database name (i.e. 'hosts.db') using the --database option. If it does not yet exist, a new database with that name will be created. All resolved hosts and classes during a jdresolve run will be cached to the database.
After you have some data in a db, you can use --dumpdb to look at it. With --mergedb to add new information to it (the format of the input file is the same as the one from a dump using --dumpdb, e.g. an ip/class followed by the hostname/classname, separated by white space)
Ex: echo "0.0.0.0 testip" | jdresolve --database hosts.db --mergedb -
...adds and IP entry to the db
Ex: echo "0.0.0 classname" | jdresolve --database hosts.db --mergedb -
...adds a class entry to the db
Note: Since when recursing the resolved hostnames are stored to the database (even when resolved by recursion), you _may_ not want to use the same database for normal and recursed runs. That is because a cached host from a resolved run will show up as a "real" IP if you don't recurse and use the --dbfirst or --dbonly options, or just use the database and the lookup times out. Nothing too serious, but this detail may be important to some people.
SOME NOTES ON NET::DNS
It seems that Net::DNS can perform suboptimally on non-Linux machines, even on *BSD (this is based on some bug reports I got from people using jdresolve in those environments). Also, on Windows NT (yes, some people still use that), you should make sure there is a 'resolv.conf' file somewhere (I'm no NT expert, read the docs). Since we use so little of the functionality of Net::DNS, I may replace it with standard sockets some time in the future. It is still a very very nice module though :)
SUPPORT
If you have dificulties using this program or would like to request a new feature, feel free to reach me at me@jdrowell.com.
LICENSING
jdresolve is licensed under the GPL. See the COPYING file for details.
jdresolve-0.6.1.orig/TODO 0100644 0001750 0000144 00000001172 07172547275 014207 0 ustar mvela users
* To do:
+ negative caching
+ progress bar (with ETA)
+ resolve the last few unresolved IPs. I'm looking into a whois
lookup or a "closest hop" approach
+ arrange benchmarks into a comprehensive table
+ test with Perl 5.6.0 (waiting for woody packages :P)
* Done:
+ direct STDIN input (0.3)
+ add ability to edit databases create with "--database"
(0.5.1)
+ clean up "dangling" A/B/C class sockets during run (0.6.0)
+ expire database entries (0.6.0)
+ further optimizations (getresolved()) (0.6.0)
jdresolve-0.6.1.orig/TODO.html 0100644 0001750 0000144 00000001074 07172541254 015142 0 ustar mvela users
- To do:
- negative caching
- progress bar (with ETA)
- resolve the last few unresolved IPs. I'm looking into a whois lookup or a "closest hop" approach
- arrange benchmarks into a comprehensive table
- test with Perl 5.6.0 (waiting for woody packages :P)
- Done:
- direct STDIN input (0.3)
- add ability to edit databases create with "--database" (0.5.1)
- clean up "dangling" A/B/C class sockets during run (0.6.0)
- expire database entries (0.6.0)
- further optimizations (getresolved()) (0.6.0)
jdresolve-0.6.1.orig/configure 0100755 0001750 0000144 00000003657 07172546702 015432 0 ustar mvela users #!/bin/sh
### Check for Perl
echo -n "checking for Perl... "
PERL=""
PERLVERSION="0"
for i in [ /usr/bin/perl /usr/local/bin/perl /bin/perl ]; do
if test -x $i; then
PERL=$i
PERLVERSION=`$PERL -e "print $]" 2>&1`
echo "found $PERLVERSION ($PERL)"
break
fi
done;
if [ "$PERL" == "" ]; then
echo "missing"
echo "You can get Perl at http://www.perl.org"
exit
fi
if [ "$PERLVERSION" \< "5.00400" ]; then
echo "We need Perl >= 5.004. You can get Perl at http://www.perl.org"
exit
fi
### Check for Net::DNS
echo -n "checking for Net::DNS... "
NETDNS=""
NETDNSVERSION="0"
INC=`$PERL -e "print join(' ', @INC)"`
for i in $INC; do
i=$i/Net/DNS.pm
if test -f $i; then
NETDNS=$i
NETDNSVERSION=`$PERL -e "use Net::DNS;print Net::DNS->version" 2>&1`
echo "found $NETDNSVERSION ($NETDNS)"
break
fi
done;
if [ "$NETDNS" == "" ]; then
echo "missing"
echo "You can get Net::DNS at http://www.cpan.org"
exit
fi
if [ "$NETDNSVERSION" \< "0.12" ]; then
echo "We need Net::DNS >= 0.12. You can get Net::DNS at http://www.cpan.org"
exit
fi
### Check for install
echo -n "checking for install... "
INSTALL=""
INSTALLVERSION=""
for i in [ /usr/bin/install /usr/local/bin/install /bin/install ]; do
if test -x $i; then
INSTALL=$i
INSTALLVERSION=`install --version | head -n 1 | sed -e "s/[^0-9]*\([0-9]*\.[0-9]*[a-z]*\)$/\1/" 2>&1 `
echo "found $INSTALLVERSION ($INSTALL)"
break
fi
done;
if [ "$INSTALL" == "" ]; then
echo "missing"
echo "You can get install from the fileutils package at ftp://ftp.gnu.org"
exit
fi
if [ "$INSTALLVERSION" \< "3.0" ]; then
echo "We need install >= 3.0. You can get install from the fileutils package at ftp://ftp.gnu.org"
exit
fi
### Create the output files
echo "creating Makefile"
cp Makefile.in Makefile
echo "creating jdresolve"
sed -e "s|^#\!/usr/bin/perl|#\!$PERL|" < jdresolve.in > jdresolve
chmod 755 jdresolve
echo ""
echo "Done. Type \"make install\" to install jdresolve."
jdresolve-0.6.1.orig/jdresolve 0100755 0001750 0000144 00000063724 07172546703 015450 0 ustar mvela users #!/usr/bin/perl -w
# jdresolve - Resolves IP addresses into hostnames
#
# Copyright (c) 1999-2000 John D. Rowell
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
=head1 NAME
jdresolve - resolves IP addresses into hostnames
=head1 SYNOPSIS
B [-h] [-v] [-n] [-r] [-a] [-d ]
[-m ] [-l ] [-t ] [-p]
[-s ] [--database=]
>
B [--help] [--version] [--nostats] [--recursive]
[--anywhere] [--debug=] [--mask=]
[--linecache=] [--timeout=]
[--sockets=] [--database=]
[--dbfirst] [--dbonly] [--dumpdb] [--mergedb]
[--expiredb=] [--unresolved] [--progress]
>
=head1 DESCRIPTION
B resolves IP addresses to hostnames. Any file
format is supported, including those where the line does
not begin with the IP address. One of the strongest
features of the program is the support for recursion,
which can drastically reduce the number of unresolved
hosts by faking a hostname based on the network that the
IP belongs to. DNS queries are sent in parallel, which
means that you can decrease run time by increasing the
number of simultaneous sockets used (given a fast enough
machine and available bandwidth ). By using the database
support, performance can be increased even further, by
using cached data from previous runs.
=head1 OPTIONS
=over 8
=item B<-h, --help>
produces a short help message
=item B<-v, --version>
display version information
=item B<-n, --no-stats>
don't display stats after processing
=item B<-r, --recursive>
recurse into C, B and A classes when there is no
PTR (default is no recursion)
=item B<-d, --debug=>
debug mode - no file output, just statistics
during run (verbosity level range: 1-3)
=item B<-t, --timeout=>
timeout in seconds for each host resolution
(default is 30 seconds)
=item B<-l, --line-cache=>
numbers of lines to cache in memory (default is
10000
=item B<-s, --sockets=>
maximum number of concurrent sockets (use ulimit
-a to check the max allowed for your operating
system - defaults to 64)
=item B<-m, --mask=>
accepts %i for IP and %c for class owner,
e.g. "somewhere.in.%c" or "%i.in.%c" (default is
"%i.%c")
=item B<-a, --anywhere>
resolves IPs found anywhere on a line (will
resolve all IPs if there is more than one)
=item B<-p, --progress>
prints a nice progress bar indicating the status
of the resolve operations
=item B<--database=>
path to database that holds resolved hosts/classes
=item B<--dbfirst>
check if we have resolved entries in the database
before sending out DNS queries
=item B<--dbonly>
don't send DNS queries, use only resolved data in
the database
=item B<--dumpdb>
dumps a database to STDOUT
=item B<--mergedb>
merges resolved IP/classes from a file (or STDIN)
with a database
=item B<--expiredb=>
expires entries in the database that are older
than hours
=item B<--unresolved>
won't attempt to resolve IPs, only lists those
that were not resolved
=item B<>
the log filename or '-' for STDIN
=head1 EXAMPLES
jdresolve access_log > resolved_log
jdresolve -r -s 128 access_log > resolved_log
jdresolve -r --database hosts.db access_log > res_log
=head1 SEE ALSO
rhost(1)
=head1 AUTHOR
B was written by John D. Rowell ,
and is licensed under the terms of the GNU General Public
License.
The original version of this man page was written by Craig
Sanders , for the Debian GNU/Linux
package of jdresolve, and is also licensed under the terms
of the GNU GPL.
=cut
# Require variable declaration
use strict;
# Load the needed modules
use Net::DNS; # installed separately
use IO::Select;
use Getopt::Long;
use POSIX qw(strftime);
use DB_File;
#use GDBM_File;
# Global constants
my $APPNAME = 'jdresolve';
my $VERSION = '0.6.1';
my $AUTHOR = 'John D. Rowell';
my $YEAR = '1999-2000';
my $BUGS = 'bugs@jdrowell.com';
# Defaults for command line options
my %opts = ( stdin => 0, help => 0, version => 0, nostats => 0, recursive => 0, debug => 0, mask => '%i.%c', linecache => 10000, timeout => 30, sockets => 64, database => '', anywhere => 0, dbfirst => 0, dbonly => 0, dumpdb => 0, unresolved => 0, mergedb => 0, expiredb => -1, progress => 0);
# Recognized command line options
my %optctl = ( '' => \$opts{stdin},
'h' => \$opts{help},
'help' => \$opts{help},
'v' => \$opts{version},
'version' => \$opts{version},
'n' => \$opts{nostats},
'nostats' => \$opts{nostats},
'r' => \$opts{recursive},
'recursive' => \$opts{recursive},
'd' => \$opts{debug},
'debug' => \$opts{debug},
'm' => \$opts{mask},
'mask' => \$opts{mask},
'l' => \$opts{linecache},
'linecache' => \$opts{linecache},
't' => \$opts{timeout},
'timeout' => \$opts{timeout},
's' => \$opts{sockets},
'sockets' => \$opts{sockets},
'a' => \$opts{anywhere},
'anywhere' => \$opts{anywhere},
'p' => \$opts{progress},
'progress' => \$opts{progress},
'dbfirst' => \$opts{dbfirst},
'dbonly' => \$opts{dbonly},
'dumpdb' => \$opts{dumpdb},
'unresolved' => \$opts{unresolved},
'mergedb' => \$opts{mergedb},
'expiredb' => \$opts{expiredb},
'database' => \$opts{database} );
# When changing %optctl, @optlst should be updated also
my @optlst = ('', 'h', 'help', 'v', 'version', 'n', 'nostats', 'r', 'recursive', 'p', 'progress', 'd=i', 'debug=i', 'm=s', 'mask=s', 'l=i', 'linecache=i', 't=i', 'timeout=i', 's=i', 'sockets=i', 'database=s', 'a', 'anywhere', 'dbfirst', 'dbonly', 'dumpdb', 'unresolved', 'mergedb', 'expiredb=i');
# Usage information
my $usage =<] [--debug=] [-m ] [--mask=] [-l ] [--linecache=] [-t ] [--timeout=] [-s ] [--sockets=] [--progress] [--dbfirst] [--dbonly] [--dumpdb] [--unresolved] [--mergedb] [--expiredb=] [--database=]
Report bugs to $BUGS
EOF
# Version information
my $version =< or -d
debug mode (no file output, just statistics during run).
verbosity level range: 1-2
--timeout= or -t
timeout in seconds (for each host resolution).
default is 30 seconds
--sockets= or -s
maximum number of concurrent sockets to use.
(use ulimit -a to check the max allowed for your operating system)
default is 64
--mask= or -m
accepts %i for IP and %c for class owner.
ex: "somewhere.in.%c" or "%i.in.%c"
default if "%i.%c"
--linecache= or -l
numbers of lines to cache in memory.
default is 10000
--unresolved
don't resolve anything, just dump the unresolved hosts to STDOUT
--database=
path to database that holds resolved hosts/classes
--dbfirst
check if we have a cached resolved host/class in the database
before sending a DNS query
--dbonly
don't send DNS queries, use only cached data in the database
--dumpdb
dumps a database to STDOUT
--mergedb
merges input to a database
--expiredb=
expires database entries older than hours
the log filename or '-' for STDIN
EOF
exit;
}
if ($opts{version}) {
# Version requested, print and exit
print < -1) and !$opts{database}) {
print < 0, RECEIVED => 0, BOGUS => 0, RESOLVED => 0, HRESOLVED => 0, TIMEOUT => 0, STARTTIME => time(), MAXTIME => 0, TOTTIME => 0, TOTLINES => 0, TOTHOSTS => 0); # holds run time statistics
unless ($opts{dumpdb} or $opts{expiredb} > -1) {
# Check if the filename exists
$filename ne '-' and !-f $filename and die "can't find log file '$filename'";
# Try to open the file
open FILE, $filename or die "error trying to open log file '$filename'";
}
# If a database is used, try to open it and tie it to %DB
$opts{database} ne '' and (tie(%DB, 'DB_File', $opts{database}) or die "can't open database '$opts{database}'");
#$opts{database} ne '' and (tie(%DB, 'GDBM_File', $opts{database}, &GDBM_WRCREAT, 0644) or die "can't open database '$opts{database}'");
$opts{dumpdb} and dumpdb(), exit;
$opts{mergedb} and mergedb(), exit;
$opts{expiredb} > -1 and expiredb(), exit;
$opts{unresolved} and unresolved(), exit;
# MAIN LOOP
while (1) {
getlines(); # read lines from input log file
$#lines == -1 and last; # no lines after read? we're done!
makequeries(); # send async dns queries
checkresponse(); # check for dns responses
checktimeouts(); # check for dns timeouts
printresults(); # print whatever we have resolved
}
printstats(); # print the session stats before we leave
# MAIN EXIT
exit;
# SUBROUTINES
sub debug {
# debug(message, level)
# Prints debug messages
# message: any text message
# level: the minimun debug level to print the message
# RETURNS: 0 if no message printed
# 1 if message was printed
my ($message, $level) = @_;
$opts{debug} < $level and return 0;
print STDERR time(), "--> $message\n";
return 1;
}
sub dumpdb {
# dumpdb()
# Dumps a database to STDOUT
# RETURNS: 1 (always)
my $i = 1;
for (%DB) {
if ($i++ % 2) {
print "$_ ";
} else {
print "$_\n";
}
}
return 1;
}
sub mergedb {
# mergedb()
# Merges a file containing IP/hostname pairs to a database
# RETURNS: 1 (always)
while () {
my ($ipclass, $name) = split /\s+/;
$DB{$ipclass} = join(' ', ($name, 'M', time()));
}
return 1;
}
sub expiredb {
# expiredb()
# Expires entries in the database
# RETURNS: 1 (always)
my $currtime = time();
my ($i, $t) = (0, 0);
for (keys %DB) {
my ($name, $type, $time) = dbread($_);
if ($currtime - $time > $opts{expiredb} * 3600) {
delete $DB{$_};
$i++;
} else {
$t++;
}
}
print STDERR "Expired $i database entries, $t left in the database\n";
return 1;
}
sub unresolved {
# unresolved()
# Dumps the unresolved IPs from a file
# RETURNS: 1 (always)
my %ips;
while () {
!/$ipmask\s/ and next;
my $ip = "$1.$2.$3.$4";
exists $ips{$ip} and next;
$ips{$ip} = 1;
print "$ip\n";
}
return 1;
}
sub dbread {
# dbread(key)
# Reads data from the database
# key: an IP address or class
# RETURNS: (name, type, time) if lookup succeeds
# (undef, undef, undef) if lookup failed
my $key = shift;
!$opts{database} and return (undef, undef, undef);
!(exists $DB{$key}) and return (undef, undef, undef);
my $fromdb = $DB{$key};
return split(/ /, $fromdb);
}
sub dbwrite {
# dbwrite(key, name, type)
# Writes data to the database
# key: an IP address or class
# name: the resolved name
# type: N = nameserver, R = recursed, M = manual
# RETURNS: 1 if using a DB
# 0 if not using a DB
my ($key, $name, $type) = @_;
!$opts{database} and return 0;
# Don't write back stuff that came from the db
$type eq 'D' and return 1;
$DB{$key} = join(' ', ($name, $type, time()));
return 1;
}
sub addhost {
# addhost(ip)
# Adds a host to the cache/queue
# ip: an IP address (x.y.z.k)
# RETURNS: 1 (always)
# Valid values for a {RESOLVED} field:
# 'p' - pending
# 'r' - pending recursion
# 'F' - failed
# 'D' - resolved from db
# 'N' - resolved from nameserver
# 'R' - resolved thru recursion
my $ip = shift;
debug("Adding host: $ip", 2);
if (exists $hosts{$ip}) {
# Host already queued, just increment the reference count
$hosts{$ip}{COUNT}++;
} else {
# Add host to queue
$hosts{$ip}{COUNT} = 1;
$hosts{$ip}{SOCKET} = undef;
$hosts{$ip}{RESOLVED} = 'p';
($hosts{$ip}{DBNAME}, $hosts{$ip}{DBTYPE}, $hosts{$ip}{DBTIME}) = dbread($ip);
$stats{TOTHOSTS}++;
if ($opts{dbfirst} and defined $hosts{$ip}{DBNAME}) {
$hosts{$ip}{NAME} = $hosts{$ip}{DBNAME};
$hosts{$ip}{RESOLVED} = 'D';
debug("host from db: $ip $hosts{$ip}{NAME}", 2);
} else {
if ($opts{dbonly}) {
$hosts{$ip}{RESOLVED} = 'F';
} else {
push @q, $ip;
}
}
}
return 1;
}
sub removehost {
# removehost(ip)
# Removes a host from the cache
# ip: an IP address (x.y.z.k)
# RETURNS: 1 (always)
my $ip = shift;
if ($opts{progress}) {
if ($progresschars % 50 == 0) {
printf STDERR "\n%10d: ", $progresschars;
}
$progresschars++;
my $status = $hosts{$ip}{RESOLVED};
$status =~ tr/NRD/.rd/;
print STDERR $status;
}
# Decrement reference count
if (--$hosts{$ip}{COUNT} < 1) {
# No more references, so remove host from cache
# Check if host was resolved
if (index('DNR', $hosts{$ip}{RESOLVED}) >= 0) {
$stats{HRESOLVED}++;
dbwrite($ip, $hosts{$ip}{NAME}, $hosts{$ip}{RESOLVED});
}
freesocket($hosts{$ip}{SOCKET});
delete $hosts{$ip};
debug("Removed host: $ip", 2);
}
return 1;
}
sub addclass {
# addclass(ip)
# Adds the classes of a host to the cache/queue
# ip: an IP address (x.y.z.k)
# RETURNS: 1 (always)
# Valid values for a {RESOLVED} field:
# 'p' - pending
# 'F' - failed
# 'D' - resolved from db
# 'N' - resolved from nameserver
my $ip = shift;
$ip =~ /$ipmask/;
# Extract the classes this host belongs to and queue them
for ("$1.$2.$3", "$1.$2", "$1") {
debug("Adding class: $_", 2);
if (exists $class{$_}) {
# Class already queued, just increment the reference count
$class{$_}{COUNT}++;
} else {
# Add class to queue
$class{$_}{COUNT} = 1;
$class{$_}{SOCKET} = undef;
$class{$_}{RESOLVED} = 'p';
($class{$_}{DBNAME}, $class{$_}{DBTYPE}, $class{$_}{DBTIME}) = dbread($_);
if ($opts{dbfirst} and defined $class{$_}{DBNAME}) {
$class{$_}{NAME} = $class{$_}{DBNAME};
$class{$_}{RESOLVED} = 'D';
debug("class from db: $_ $class{$_}{NAME}", 2);
} else {
if ($opts{dbonly}) {
$class{$_}{RESOLVED} = 'F';
} else {
# prioritize class in the queue
unshift @q, $_;
}
}
}
}
return 1;
}
sub removeclass {
# removeclass(ip)
# Removes all classes from an ip from the cache
# ip: an IP address (x.y.z.k)
# RETURNS: 1 (always)
my $ip = shift;
$ip =~ /$ipmask/;
for ("$1.$2.$3", "$1.$2", "$1") {
if (--$class{$_}{COUNT} < 1) {
# Last reference, if resolved store to db
$class{$_}{RESOLVED} eq 'N' and dbwrite($_, $class{$_}{NAME}, $class{$_}{RESOLVED});
freesocket($class{$_}{SOCKET});
delete $class{$_};
debug("Removed class: $_", 2);
}
}
return 1;
}
sub checkrecurse {
# checkrecurse(ip)
# Checks for classes if normal resolve failed
# ip: an IP address (x.y.z.k)
# RETURNS: 1 (always)
my $ip = shift;
debug("Check recurse $ip", 2);
$ip =~ /$ipmask/;
for ("$1.$2.$3", "$1.$2", "$1") {
# if still resolving class, return
$class{$_}{RESOLVED} eq 'p' and return 1;
# class was resolved, return class name
if ($class{$_}{RESOLVED} ne 'F') {
$hosts{$ip}{NAME} = maskthis($ip, $class{$_}{NAME});
$hosts{$ip}{RESOLVED} = 'R';
removeclass($ip);
return 1;
}
# NOTE: The order of the classes is important. If we have a
# class C resolved, no need to wait for the upper classes
}
# No luck, mark as failed
$hosts{$ip}{RESOLVED} = 'F';
removeclass($ip);
return 1;
}
sub maskthis {
# maskthis(ip, class)
# Masks a fake hostname based on an IP and a resolved class
# ip: an IP address (x.y.z.k)
# class: the class name (somewhere.com)
# RETURNS: a masked representation of the IP (x.y.z.k.somewhere.com)
my ($ip, $domain) = @_;
my $masked = $opts{mask};
$masked =~ s/%i/$ip/;
$masked =~ s/%c/$domain/;
return $masked;
}
sub getlines {
# getlines()
# Fetches lines from the file into our line buffer
# RETURNS: 1 if something was read, 0 if EOF
eof(FILE) and return 0;
my $line;
while ($#lines < $opts{linecache} - 1 and $line = ) {
my @hosts;
while ($line =~ /$ipmask/g) {
push @hosts, "$1.$2.$3.$4";
addhost("$1.$2.$3.$4");
}
$stats{TOTLINES}++;
push @lines, { TEXT => $line, HOSTS => \@hosts };
}
return 1;
}
sub makequeries {
# makequeries()
# Takes IPs and classes from the queue and sends them to the query
# function. This controls the number of sockets in use.
# RETURNS: 1 (always)
for (1..($opts{sockets} - $sel->count)) {
my $query = $q[0];
!$query and last;
my $ok = 0;
if ($query =~ /$ipmask/) {
$ok = query($query, 'H');
} elsif (exists $class{$query}) {
$ok = query($query, 'C');
} else {
debug("Out of context class $query was skipped", 3);
$ok = 1;
}
$ok ? shift @q : last;
}
return 1;
}
sub freesocket {
# freesocket(socket)
# Frees a socket from our main select and the socket itself
# RETURNS: 1 if freed
# 0 if socket didn't exist
my $socket = shift;
!(defined $socket) and return 0;
$sel->remove($socket);
my $type = $socks{fileno($socket)}{TYPE};
my $query = $socks{fileno($socket)}{QUERY};
if ($type eq 'H') {
!exists $hosts{$query} and die "no such host: $query";
undef $hosts{$query}{SOCKET};
} else {
!exists $class{$query} and die "no such class: $query";
undef $class{$query}{SOCKET};
}
delete $socks{fileno($socket)};
debug("Freed socket for query $query - socket count: " . (keys %socks) . " - " . $sel->count, 2);
return 1;
}
sub nsfailed {
# nsfailed(query, type)
# Updates statuses when nameserver resolution fails
# (bogus reply or timeout)
# query: the DNS query
# type: H for host or C for class
# RETURNS: 1 (always)
my ($query, $type) = @_;
if ($type eq 'H') {
if (defined $hosts{$query}{DBNAME}) {
$hosts{$query}{NAME} = $hosts{$query}{DBNAME};
$hosts{$query}{RESOLVED} = 'D';
} elsif ($opts{recursive}) {
$hosts{$query}{RESOLVED} = 'r';
addclass($query);
} else {
$hosts{$query}{RESOLVED} = 'F';
}
} else {
if (defined $class{$query}{DBNAME}) {
$class{$query}{NAME} = $class{$query}{DBNAME};
$class{$query}{RESOLVED} = 'D';
} else {
$class{$query}{RESOLVED} = 'F';
}
}
return 1;
}
sub checkresponse {
# checkresponse()
# Checks sockets for DNS replies and processes them
# RETURNS: 1 (always)
# Check pending replies, give it 5 seconds at most
for ($sel->can_read(5)) {
my $resolved = 0;
my $fileno = fileno($_);
my $query = $socks{$fileno}{QUERY};
my $type = $socks{$fileno}{TYPE};
my $timespan = time() - $socks{$fileno}{TIME};
$stats{TOTTIME} += $timespan;
my $packet = $res->bgread($_);
$stats{RECEIVED}++;
debug("Response for query $query (" . $sel->count . ")", 2);
# Got the reply and saved the results, so free the socket
freesocket($_);
if ($packet) {
for ($packet->answer) {
# For each DNS answer, check the data received
if ($type eq 'H') {
if (defined $_->{ptrdname}) {
$hosts{$query}{NAME} = $_->{ptrdname};
$hosts{$query}{RESOLVED} = 'N';
$resolved = 1;
debug("response HOST: $query is " . $hosts{$query}{NAME}, 2);
} else {
debug("undefined response for query $query", 2);
}
} else {
my $fulldomain;
# Check for the previously used SOA records and
# the current NS records
if ($_->type eq 'SOA') { $fulldomain = $_->{mname}; }
elsif ($_->type eq 'NS') { $fulldomain = $_->{nsdname}; }
else { next; }
debug("Class: $fulldomain", 3);
my ($ns, $domain) = $fulldomain =~ /([^\.]+)\.(.*)/;
if (defined $domain) {
# Avoid truncating records with no machine name
$domain =~ /\./ or $domain = $fulldomain;
$class{$query}{NAME} = lc $domain;
$class{$query}{RESOLVED} = 'N';
$resolved = 1;
}
}
}
}
if ($resolved) {
$stats{RESOLVED}++;
$timespan > $stats{MAXTIME} and $stats{MAXTIME} = $timespan;
} else {
$stats{BOGUS}++;
nsfailed($query, $type);
}
}
return 1;
}
sub checktimeouts {
# checktimeouts()
# Checks sockets for DNS reply timeouts
# RETURNS: 1 (always)
my $now = time();
for ($sel->handles) {
# Iterate through all active sockets
my $fileno = fileno($_);
my $query = $socks{$fileno}{QUERY};
my $type = $socks{$fileno}{TYPE};
my $timespan = $now - $socks{$fileno}{TIME};
if ($timespan > $opts{timeout}) {
# We have a timeout
$stats{TIMEOUT}++;
$stats{TOTTIME} += $timespan;
# Mark query owner appropriately
nsfailed($query, $type);
freesocket($_);
}
}
return 1;
}
sub printresults {
# printresults()
# Checks if the next lines in our buffer have their IPs resolved
# and print the results to STDOUT
# RETURNS: 1 (always)
debug("Sent: $stats{SENT}, Received: $stats{RECEIVED}, Resolved: $stats{RESOLVED}, Bogus: $stats{BOGUS}, Timeout: $stats{TIMEOUT}", 1);
while ($#lines != -1) {
# We still have lines in the cache
my %line = %{$lines[0]};
!@{$line{HOSTS}} and print($line{TEXT}), shift @lines, next;
for (@{$line{HOSTS}}) {
# Check all hosts for this line (pending, recursing)
$hosts{$_}{RESOLVED} eq 'r' and checkrecurse($_);
index('pr', $hosts{$_}{RESOLVED}) >= 0 and goto done;
}
# Nothing pending for this line if we got here
for (@{$line{HOSTS}}) {
# Update line with resolved hosts
$hosts{$_}{RESOLVED} ne 'F' and $line{TEXT} =~ s/$_/$hosts{$_}{NAME}/;
# We don't need this host anymore
removehost($_);
}
print $line{TEXT};
shift @lines;
}
done:
}
sub printstats {
# printstats()
# Print the statistics gathered during program run
# RETURNS: 1 (always)
$opts{nostats} and return;
$opts{progress} and print STDERR "\n\n";
my $timespan = time() - $stats{STARTTIME};
print STDERR
" Total Lines: $stats{TOTLINES}\n",
" Total Time : ",
strftime("%H:%M:%S", gmtime($timespan)), " (",
sprintf("%.2f", $timespan ? ($stats{TOTLINES} / $timespan) : 0), " lines/s)\n",
" Total Hosts: $stats{TOTHOSTS}\n",
" Resolved Hosts: $stats{HRESOLVED} (",
sprintf("%.2f", $stats{TOTHOSTS} ? ($stats{HRESOLVED} / $stats{TOTHOSTS} * 100) : 0), "%)\n",
"Unresolved Hosts: ",
$stats{TOTHOSTS} - $stats{HRESOLVED}, " (",
sprintf("%.2f", $stats{TOTHOSTS} ? (($stats{TOTHOSTS} - $stats{HRESOLVED}) / $stats{TOTHOSTS} * 100) : 0), "%)\n",
"Average DNS time: ",
sprintf("%.4f", $stats{SENT} ? ($stats{TOTTIME} / $stats{SENT}) : 0), "s per request\n",
" Max DNS time: ", $stats{MAXTIME}, "s (consider this value for your timeout)\n";
debug("\n\nhosts: " . scalar(keys %hosts) . "\nclasses: " . scalar(keys %class) . "\nselect: " . $sel->count . "\n", 1);
return 1;
}
sub query {
# query()
# Sends out an assynchronous DNS query
# RETURNS: 1 if successful
# 0 if failed (no free sockets)
my ($find, $type) = @_;
my $send = ($type eq 'H') ? $find : (join('.', reverse(split(/\./, $find))) . '.in-addr.arpa');
# Send a query of format PTR for hosts or NS for classes
my $sock = $res->bgsend($send, ($type eq 'H') ? 'PTR' : 'NS');
if (!$sock) {
# We're out of sockets. Warn the user and continue
print STDERR "Error opening socket for bgsend. Are we out of sockets?\n";
return 0;
}
$stats{SENT}++;
$sel->add($sock);
# Make a socket record for cross referencing
my $fileno = fileno($sock);
$socks{$fileno}{TIME} = time();
$socks{$fileno}{QUERY} = $find;
$socks{$fileno}{TYPE} = $type;
debug("Sent query of type $type: $find", 2);
# Update the owner of the socket also for easy referencing
$type eq 'H' ? ($hosts{$find}{SOCKET} = $sock) : ($class{$find}{SOCKET} = $sock);
return 1;
}
jdresolve-0.6.1.orig/jdresolve.1 0100600 0001750 0000144 00000021427 07172547274 015572 0 ustar mvela users .rn '' }`
''' $RCSfile$$Revision$$Date$
'''
''' $Log$
'''
.de Sh
.br
.if t .Sp
.ne 5
.PP
\fB\\$1\fR
.PP
..
.de Sp
.if t .sp .5v
.if n .sp
..
.de Ip
.br
.ie \\n(.$>=3 .ne \\$3
.el .ne 3
.IP "\\$1" \\$2
..
.de Vb
.ft CW
.nf
.ne \\$1
..
.de Ve
.ft R
.fi
..
'''
'''
''' Set up \*(-- to give an unbreakable dash;
''' string Tr holds user defined translation string.
''' Bell System Logo is used as a dummy character.
'''
.tr \(*W-|\(bv\*(Tr
.ie n \{\
.ds -- \(*W-
.ds PI pi
.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
.ds L" ""
.ds R" ""
''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of
''' \*(L" and \*(R", except that they are used on ".xx" lines,
''' such as .IP and .SH, which do another additional levels of
''' double-quote interpretation
.ds M" """
.ds S" """
.ds N" """""
.ds T" """""
.ds L' '
.ds R' '
.ds M' '
.ds S' '
.ds N' '
.ds T' '
'br\}
.el\{\
.ds -- \(em\|
.tr \*(Tr
.ds L" ``
.ds R" ''
.ds M" ``
.ds S" ''
.ds N" ``
.ds T" ''
.ds L' `
.ds R' '
.ds M' `
.ds S' '
.ds N' `
.ds T' '
.ds PI \(*p
'br\}
.\" If the F register is turned on, we'll generate
.\" index entries out stderr for the following things:
.\" TH Title
.\" SH Header
.\" Sh Subsection
.\" Ip Item
.\" X<> Xref (embedded
.\" Of course, you have to process the output yourself
.\" in some meaninful fashion.
.if \nF \{
.de IX
.tm Index:\\$1\t\\n%\t"\\$2"
..
.nr % 0
.rr F
.\}
.TH JDRESOLVE 1 "perl 5.005, patch 03" "16/Oct/2000" "User Contributed Perl Documentation"
.UC
.if n .hy 0
.if n .na
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.de CQ \" put $1 in typewriter font
.ft CW
'if n "\c
'if t \\&\\$1\c
'if n \\&\\$1\c
'if n \&"
\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
'.ft R
..
.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
. \" AM - accent mark definitions
.bd B 3
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds ? ?
. ds ! !
. ds /
. ds q
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
.ds oe o\h'-(\w'o'u*4/10)'e
.ds Oe O\h'-(\w'O'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds v \h'-1'\o'\(aa\(ga'
. ds _ \h'-1'^
. ds . \h'-1'.
. ds 3 3
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
. ds oe oe
. ds Oe OE
.\}
.rm #[ #] #H #V #F C
.SH "NAME"
jdresolve \- resolves IP addresses into hostnames
.SH "SYNOPSIS"
\fBjdresolve\fR [\-h] [\-v] [\-n] [\-r] [\-a] [\-d ]
[\-m ] [\-l ] [\-t ] [\-p]
[\-s ] [--database=]
<\fILOG FILE\fR>
.PP
\fBjdresolve\fR [--help] [--version] [--nostats] [--recursive]
[--anywhere] [--debug=] [--mask=]
[--linecache=] [--timeout=]
[--sockets=] [--database=]
[--dbfirst] [--dbonly] [--dumpdb] [--mergedb]
[--expiredb=] [--unresolved] [--progress]
<\fILOG FILE\fR>
.SH "DESCRIPTION"
\fBjdresolve\fR resolves IP addresses to hostnames. Any file
format is supported, including those where the line does
not begin with the IP address. One of the strongest
features of the program is the support for recursion,
which can drastically reduce the number of unresolved
hosts by faking a hostname based on the network that the
IP belongs to. DNS queries are sent in parallel, which
means that you can decrease run time by increasing the
number of simultaneous sockets used (given a fast enough
machine and available bandwidth ). By using the database
support, performance can be increased even further, by
using cached data from previous runs.
.SH "OPTIONS"
.Ip "\fB\-h, --help\fR" 8
produces a short help message
.Ip "\fB\-v, --version\fR" 8
display version information
.Ip "\fB\-n, --no-stats\fR" 8
don't display stats after processing
.Ip "\fB\-r, --recursive\fR" 8
recurse into C, B and A classes when there is no
\s-1PTR\s0 (default is no recursion)
.Ip "\fB\-d, --debug=" 8
debug mode \- no file output, just statistics
during run (verbosity level range: 1-3)
.Ip "\fB\-t, --timeout=" 8
timeout in seconds for each host resolution
(default is 30 seconds)
.Ip "\fB\-l, --line-cache=" 8
numbers of lines to cache in memory (default is
10000
.Ip "\fB\-s, --sockets=" 8
maximum number of concurrent sockets (use ulimit
\-a to check the max allowed for your operating
system \- defaults to 64)
.Ip "\fB\-m, --mask=" 8
accepts \f(CW%i\fR for \s-1IP\s0 and \f(CW%c\fR for class owner,
e.g. \*(L"somewhere.in.%c\*(R" or \*(L"%i.in.%c\*(R" (default is
\*(L"%i.%c")
.Ip "\fB\-a, --anywhere\fR" 8
resolves IPs found anywhere on a line (will
resolve all IPs if there is more than one)
.Ip "\fB\-p, --progress\fR" 8
prints a nice progress bar indicating the status
of the resolve operations
.Ip "\fB--database=" 8
path to database that holds resolved hosts/classes
.Ip "\fB--dbfirst\fR" 8
check if we have resolved entries in the database
before sending out \s-1DNS\s0 queries
.Ip "\fB--dbonly\fR" 8
don't send \s-1DNS\s0 queries, use only resolved data in
the database
.Ip "\fB--dumpdb\fR" 8
dumps a database to \s-1STDOUT\s0
.Ip "\fB--mergedb\fR" 8
merges resolved \s-1IP/\s0classes from a file (or \s-1STDIN\s0)
with a database
.Ip "\fB--expiredb=" 8
expires entries in the database that are older
than hours
.Ip "\fB--unresolved\fR" 8
won't attempt to resolve IPs, only lists those
that were not resolved
.Ip "\fB<\s-1LOG\s0 \s-1FILE\s0\fR>" 8
the log filename or \*(L'\-\*(R' for \s-1STDIN\s0
.SH "EXAMPLES"
.Sp
.Vb 3
\& jdresolve access_log > resolved_log
\& jdresolve -r -s 128 access_log > resolved_log
\& jdresolve -r --database hosts.db access_log > res_log
.Ve
.SH "SEE ALSO"
\fIrhost\fR\|(1)
.SH "AUTHOR"
\fBjdresolve\fR was written by John D. Rowell ,
and is licensed under the terms of the GNU General Public
License.
.Sp
The original version of this man page was written by Craig
Sanders , for the Debian GNU/Linux
package of jdresolve, and is also licensed under the terms
of the GNU GPL.
.rn }` ''
.IX Title "JDRESOLVE 1"
.IX Name "jdresolve - resolves IP addresses into hostnames"
.IX Header "NAME"
.IX Header "SYNOPSIS"
.IX Header "DESCRIPTION"
.IX Header "OPTIONS"
.IX Item "\fB\-h, --help\fR"
.IX Item "\fB\-v, --version\fR"
.IX Item "\fB\-n, --no-stats\fR"
.IX Item "\fB\-r, --recursive\fR"
.IX Item "\fB\-d, --debug="
.IX Item "\fB\-t, --timeout="
.IX Item "\fB\-l, --line-cache="
.IX Item "\fB\-s, --sockets="
.IX Item "\fB\-m, --mask="
.IX Item "\fB\-a, --anywhere\fR"
.IX Item "\fB\-p, --progress\fR"
.IX Item "\fB--database="
.IX Item "\fB--dbfirst\fR"
.IX Item "\fB--dbonly\fR"
.IX Item "\fB--dumpdb\fR"
.IX Item "\fB--mergedb\fR"
.IX Item "\fB--expiredb="
.IX Item "\fB--unresolved\fR"
.IX Item "\fB<\s-1LOG\s0 \s-1FILE\s0\fR>"
.IX Header "EXAMPLES"
.IX Header "SEE ALSO"
.IX Header "AUTHOR"
jdresolve-0.6.1.orig/jdresolve.1.gz 0100644 0001750 0000144 00000007257 07172547274 016226 0 ustar mvela users 9 9[[HWzHdY6 #N&1C[j]L3~eR[<ۆ,?wg 杜E&碔 ҩ9r&2I$X]ww