#!/usr/bin/perl

use Getopt::Long;

$fullpath  = $0;
($progname = $0) =~ s#.*/##;

$remctl = '/usr/bin/remctl';

$usage = <<"EOL";

  usage: $progname [-d <days>] [-r <rows>] [-f <file>] [-amvs] name|addr ...

    Search for IP address names, IP addresses (dotted decimal format), or
    hardware addresses (in hex, with optional ':' or '-' delimiters)

    -a         display the IP address name instead of the NetDB entry name
    -d <days>  search for hosts last seen within this many days, default 30
    -f <file>  get names/addresses to look up from this file
    -h         print detailed usage instructions
    -m         print matches only
    -r <rows>  limit search results this many matches, default 1000
    -s         script-oriented output
    -u         print this message
    -v         verbose output

EOL

Getopt::Long::config("pass_through");

GetOptions("f|file=s" => \$infile,
           "h|help"   => \$help,
           "u|usage"  => \$display_usage) or usage();

help()  if $help;
usage() if $display_usage;

# if an input file was specified, add its contents to the arguments
if ($infile && (open(IN, $infile) or die "Can't open file '$infile': $!\n")) {
    while(<IN>) { push @ARGV, split; }  close(IN);
}

exec $remctl, "netdb-ipm-rc.stanford.edu", "netdb", "ipm", @ARGV
  or die "Unable to exec remctl: $!\n";

sub usage { die $usage }
sub help  { exec ('perldoc', $fullpath) or die "$fullpath: can't exec: $!\n" }


__END__


############################################################################
# Documentation
############################################################################


=head1 NAME

ipm - Search for IP address names, IP or hardware addresses

=head1 SYNOPSIS

ipm [B<-d> I<days>] [B<-r> I<rows>] [B<-f> I<file>] [B<-amvs>] I<name|IPaddr|HWaddr>

=head1 DESCRIPTION

Networking Systems collects data on network usage and stores that data
in a database.  The database contains observed instances of the use of
individual IP addresses and hardware (e.g. Ethernet) addresses, along
with the DNS name of the IP address and the NetDB address type.  These
data are collected from the network several times per day.  For each (IP
address, hardware address, DNS name, IP address type) tuple the database
keeps track of the first time it was seen, the last time it was seen,
and how many times it has been seen.

B<ipm> searches this database using the conditions you supply and displays
the matching records.  You can search the database by name (the DNS name
of the IP address at the time it was detected), IP address, or hardware
address.  IP addresses can be entered in a variety of formats using Unix
or SQL wildcards.  B<ipm> recognizes virtually all popular hardware address
formats, but hardware addresses must be complete, i.e. they must contain
exactly 12 hex digits.  B<ipm> searches only unqualified host names, so
entering a name with a domain will probably not yield any matches.  Here
are some examples of acceptable input and how they are interpreted by
B<ipm>:

                   INPUT  TYPE         VALUE(S)
 =======================  ===========  =============================
             171.64.20.3  ip address   171.64.20.3
               171.64.20  ip address   171.64.20.0
              171.64.20.  ip address   171.64.20.0

          171.64.20.7/24  ip range     171.64.20.0  - 171.64.20.255
            171.64.20/25  ip range     171.64.20.0  - 171.64.20.127
         171.64.106.0/23  ip range     171.64.106.0 - 171.64.107.255
 171.64.2.1-171.64.2.100  ip range     171.64.2.1   - 171.64.2.100
          161.64.12.1-10  ip range     161.64.12.1  - 161.64.12.10
         161.64.12.42-43  ip range     161.64.12.42 - 161.64.12.43
     171.64.20-171.64.21  ip range     171.64.20.0  - 171.64.21.0
           171.64.20./23  ip range     171.64.20.0  - 171.64.21.255

             171.64.20.*  ip wildcard  171.64.20.%
             171.64.20.%  ip wildcard  171.64.20.%
              171.64.*.1  ip wildcard  171.64.%.1
                171.65.*  ip wildcard  171.65.%

       08:00:20:85:8b:0f  hw address   080020858b0f
         08:0:20:85:8b:f  hw address   080020858b0f
       08-00-20-85-8b-0f  hw address   080020858b0f
         8-00-20-85-8b-f  hw address   080020858b0f
          0800.2085.8b0f  hw address   080020858b0f
           080020:858b0f  hw address   080020858b0f
           080020858b0f:  hw address   080020858b0f
            080020858b0f  hw address   080020858b0f

                    jan*  name         jan%
                   camel  name         camel
                  da__d%  name         da__d%
                   sn?w*  name         sn_w%

Results can be displayed in three formats: a screen-oriented table with
one line per matching record (this is the default output format);
multiple lines per matching record with one labeled piece of data per
line (option B<-v>), and; script-oriented output with the data for each
matching record glued together with vertical bars, '|' (option B<-s>).

An IP address displayed by B<ipm> has 2 names - the name it had at the
time it was detected on the network and the current name in NetDB.
The default screen-oriented display has only enough space to display
one name so the NetDB name is displayed.  The B<-a> (address names)
option tells B<ipm> to display the name of the address at the time it
was detected.

An IP address also has a I<type>.  In NetDB an IP addresses can be
assigned to a node interface, or assigned to a node as an IP
connectivity provider address, or assigned to a Network as a dynamic
DHCP address.  B<ipm> displays the type of the IP address when the
address was detected on the network, not the current NetDB type of the
address.  If the IP address wasn't in NetDB when it was detected, the
type is "Unknown".  B<ipm> displays the IP address type differently in
each of the three output formats; here's how it looks in each:

    verbose         default  script
    ==============  =======  ======
    Dynamic DHCP         d      dyn
    IPC                  i      ipc
    Node Interface       n      int
    Unknown              u      unk

=head1 OPTIONS

=over 4

=item B<-a>, B<--addressnames>

Display the IP address name instead of the NetDB entry name.

=item B<-d> I<days>, B<--days> I<days>

Search for hosts last seen within this many days, default 30.

=item B<-f> I<file>, B<--file> I<file>

Get names/addresses to look up from I<file>.

=item B<-h>, B<--help>

Print this message.

=item B<-m>, B<--matchonly>

Print matches only.

=item B<-r> I<rows>, B<--rows> I<rows>

Limit search results this many matches, default 1000.

=item B<-s>, B<--script>

Script-oriented output.

=item B<-u>, B<--usage>

Print short usage instructions.

=item B<-v>, B<--verbose>

Verbose output.

=cut
