#!/bin/sh
# the next line restarts using scotty -*- tcl -*- \
exec scotty "$0" "$@"

package require Tnm 2.1

##
## Send a snmp request to all ip addresses on a class C like
## network. Use with care as this script floods you network! It is
## just an example how fast asynchronous SNMP operations can work.
##

proc SnmpDiscover {net delay window retries timeout} {
    for {set i 1} {$i < 255} {incr i} {
	set s [snmp session -address $net.$i -delay $delay -window $window \
	       -retries $retries -timeout $timeout]
	$s get sysDescr.0 {
	    if {"%E" == "noError"} {
		set d [lindex [lindex {%V} 0] 2]
		regsub -all "\[\n\r\]" $d "" d
		puts "[%S cget -address]\t$d"
	    }
	    %S destroy
	}
	update
    }
    snmp wait
}

##
## Send an icmp echo request to all ip addresses on a class C like
## network. Use with care as this script floods you network! 
## It is just an example how fast our icmp command can work.
##

proc IcmpDiscover {net delay window retries timeout} {
    set hosts ""
    for {set i 1} {$i < 255} {incr i} {
	lappend hosts $net.$i
    }
    if {[catch {icmp -delay $delay -retries $retries -timeout $timeout \
	echo $hosts} result]} {
	puts stderr $result
	continue
    }
    foreach elem $result {
	set ip  [lindex $elem 0]
	set rtt [lindex $elem 1]
	if {$rtt >= 0} {
	    puts "$ip\ticmp echo $rtt ms"
	}
    }
}

if {$argv == ""} {
    puts stderr {usage: discover [-d delay] [-r retries] [-t timeout] [-w window] [-snmp] [-icmp] networks}
    exit 42
}

mib load rfc1213.mib

set discover SnmpDiscover
set delay 10
set window 255
set retries 2
set timeout 5

set newargv ""
set parsing_options 1
while {([llength $argv] > 0) && $parsing_options} {
    set arg [lindex $argv 0]
    set argv [lrange $argv 1 end]
    if {[string index $arg 0] == "-"} {
	switch -- $arg  {
	    "-d"    {
		        set delay [lindex $argv 0]
		        set argv  [lrange $argv 1 end]
                    }
	    "-r"    {
		        set retries [lindex $argv 0]
		        set argv    [lrange $argv 1 end]
                    }
	    "-t"    {
		        set timeout [lindex $argv 0]
		        set argv    [lrange $argv 1 end]
                    }
	    "-w"    {
		        set window [lindex $argv 0]
		        set argv   [lrange $argv 1 end]
                    }
	    "-snmp" { set discover SnmpDiscover }
	    "-icmp" { set discover IcmpDiscover }
	    "--"    { set parsing_options 0 }
	}
    } else {
	set parsing_options 0
	lappend newargv $arg
    }
}
set argv [concat $newargv $argv]

foreach network $argv {
    switch -regexp $network {
	{^[0-9]+\.[0-9]+$} {
	    for {set i 1} {$i < 255} {incr i} {
		$discover $network.$i $delay $window $retries $timeout
	    }
	}
	{^[0-9]+\.[0-9]+\.[0-9]+$} {
	    $discover $network $delay $window $retries $timeout
	}
	default {
	    puts stderr "network $network ignored (invalid format)"
	}
    }
}

exit
