#!/usr/bin/perl -w
eval 'exec perl -S $0 "$@"'
    if 0;
#
# ipsort - Sort by the first IP address found anywhere on a line
#          Copyright (C) 2004 by James S. Seymour, Release 0.0.2
#	   (See "License", below.)
#
# Usage
#
#    ipsort [-a] [-u] <file(s)>
#
#        -a Address only - Emit IP address(es) only
#        -u Unique - Remove lines with duplicate IP addresses
#
#    ipsort [-c] [-i] [-t<n>] <file(s)>
#
#        -c Count - Emit per-IP counts, sorted by count
#        -i IP sort - Sort by IP (with -t only)
#     -t<n> Trim octets - Elide last <n> octets (with -c only)
#
# Notes
#
#    If the input consists of lines with and without IP addresses
#    in them, lines lacking IP addresses will appear first.  If
#    -a (address only) or -c (count) was specified, "blanks" will
#    be suppressed.
#
# The IPSort Home Page is at:
#
#    http://jimsun.LinxNet.com/unix_utils_by_jim.html
#
# License:
#    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 may 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.
#    
#    An on-line copy of the GNU General Public License can be found
#    http://www.fsf.org/copyleft/gpl.html.
#
use strict;
use Getopt::Std;

(my $progName = $0) =~ s/^.*\///o;

my $usageMsg = "Usage: $progName [-a] [-u] <file(s)>
       $progName [-c] [-i] [-t<n>] <file(s)>";

my (@fLines, %ipAddrs, $indx, $mem, %ipCnts);

use vars qw($opt_a $opt_u $opt_c $opt_i $opt_t);
getopts('aucit:') || die "$usageMsg: $!

       -a Address only - Emit IP address(es) only
       -u Unique - Remove lines with duplicate IP addresses
       -c Count - Emit per-IP counts, sorted by count
       -i IP sort - Sort by IP (with -t only)
    -t<n> Trim octets - Elide last <n> octets (with -c only)
\n";

while(<>) {
    push(@fLines, $_);
    $ipAddrs{$indx++} = /((?:\d{1,3}\.){3}\d{1,3})/o? pack('C4', split(/\./, $1)) : "";
}

if($opt_c) {
    my $octets = ($opt_t? 4 - $opt_t : 4);
    my $packStr = sprintf("C%d", $octets);

    foreach (keys %ipAddrs) {
	next unless($ipAddrs{$_});
	if($opt_t) {
	    $ipAddrs{$_} = pack($packStr, unpack("C4", $ipAddrs{$_}));
	}
	++$ipCnts{$ipAddrs{$_}};
    }

    foreach (map { $_->[0] }
	     sort {
		    if($opt_i) {
			$a->[0] cmp $b->[0] || $b->[1] <=> $a->[1];
		    } else {
			$b->[1] <=> $a->[1] || $a->[0] cmp $b->[0];
		    }
		  }
	     map { [ $_, $ipCnts{$_} ] }
	     (keys(%ipCnts)))
    {
	printf("%4d %s\n", $ipCnts{$_}, join(".", unpack($packStr, $_)));
    }
} else {
    foreach (sort { $ipAddrs{$a} cmp $ipAddrs{$b} } keys %ipAddrs) {
	next if($opt_u && $mem && $ipAddrs{$_} eq $mem);
	if($opt_a) {
	    print join(".", unpack("C4", $ipAddrs{$_})) . "\n" if($ipAddrs{$_});
	} else {
	    print "$fLines[$_]";
	}
	$mem = $ipAddrs{$_} if($opt_u);
    }
}

