The most ubiquitous tools are going to be a simple borne style shall and ping I guess. You'd have to watch out for different ping versions on Linux, the BSDs, other Unixes (things like return values have a nasty trick of changing subtly across the different *nixes...
Components of the script would be a function to turn an IP spec with ranges into a list of IPs, i.e. which takes a parameter like "192.168.1.1-3" and returns "192.168.1.1 192.168.1.2 192.168.1.3". Then you can iterate over the list and call another function which does the actual ping.
ping itself would end up being called and the return value tested something like this:
Code:
ping -W 3 -c 3 $IP > /dev/null
if [ $? -eq 0 ]; then
echo $IP >> success.log
fi
And then at the end of it all, the file success.log contains the IPs which were reachable.
Clearly if you do all the pings one after the other it's going to be very slow, so you'll want to use shell job control to achieve some degree of parallelism. Launching off groups of ping in the background and calling "wait" is the way to do this.
To my mind easiest (if not optimal) way to do it would be split the list of IPs into groups of some number, launch that number of IP checks in parallel, wait for the result, and then do the next group.
If you have multiple ping appending to some log file in parallel, you might have trouble with un-ordered writing to the log file... this is probably the hardest part to work around. I am not sure if the shell append re-direction operator >> will suffer from this problem or not - perhaps. If this is the case, you might create a directory for the results and touch a file for each positive result, deleting them once you've finished the check.