#!/usr/bin/perl -- -*- perl -*-
###########################################################################
# netsort.pl
# David Simmons <simmons@simmons.starkville.ms.us>
#
# This script sorts network addresses based on their distance in hops
# from the local server.
#
# purpose: If you have a list of servers that carry a needed service,
#          and you want to connect to the closest one, you can use this
#          script to determine which ones are closest.  For example, if
#          you wanted to mirror an ftp archive, and you had several sites
#          to choose from.
#
# bugs:    Uses "ping", which has different behavior on different platforms.
#
###########################################################################

#
# $MAX_HOPS contains the maximum reasonable number of hops.
#

$MAX_HOPS = 64;

while ($addr = <>) {
    chop $addr;
    open(PING,"ping -c 1 -i 1 $addr |") || die("cannot run ping");
    $ttl=0;
    while (<PING>) {
	if (/ttl=(\d*)/) {
	    $ttl=$1;
	}
    }
	if ($ttl < 32) {
		$ttl += 224;
	}
	if ($ttl < 64) {
		$ttl += 192;
	}
	if ($ttl < 128) {
		$ttl += 128;
	}
    $list{$addr} = $ttl;
    close(PING);
}

for $i (sort { $list{$b} <=> $list{$a} } keys(%list)) {
    $hops = 256 - $list{$i};
    if ($hops == 256) {
	printf("[ping error!] %s\n", $i);
    } else {
	if ($hops < $MAX_HOPS) {
	    printf("%3d hops: %s\n", $hops, $i);
	} else {
	    printf("[bad ttl val] %s\n", $i);
	}
    }
}
