#!/bin/sh
# Tcl sees the next lines as an assignment to variable `kludge'.
# For sh, the two shifts cancel the effect of the set, and then we
# run scotty on this script.

set kludge { $*
    shift
    shift
    if test -x ../scotty ; then
      exec ../scotty -nf $0 $*
    else
      exec scotty -nf $0 $*
    fi
}

proc udp_send { file host delay } {

    global msg stat size
    
    if {[catch {udp send $file $msg} err]} {
	catch {
	    removeinput $file
	    udp close $file
	}
	return
    }
    
    incr stat(send,$host) $size
    
    after $delay "udp_send $file $host $delay"
}

proc udp_receive { file host } {

    global stat size
    
    udp receive $file
    incr stat(received,$host) $size
}

proc udp_summary { file host secs } {

    global stat

    removeinput $file
    udp close $file

    set send $stat(send,$host)
    set received $stat(received,$host)

    set o_speed [expr {$send/1024.0/$secs}]
    set i_speed [expr {$received/1024.0/$secs}]
    set loss    [expr {($send-$received)/double($send)*100}]
    
    puts [format "%6.2f kB/s send %6.2f kB/s received %6.2f %% loss (%s)" \
	  $o_speed $i_speed $loss $host ]
}

##
## Connect a udp file handle to the echo port on host and send datagrams
## to it. Calculate the throughput in kB per second and the loss rate.
##

proc udp_echo { host secs len delay } {

    global msg stat size

    set size $len

    set msg ""
    for {set len 0} {$len < $size} {incr len} {append msg "+"}

    set stat(send,$host) 0
    set stat(received,$host) 0

    if {[catch {udp connect $host echo} f]} {
	puts "$host: $f"
	return
    }

    addinput -read $f "udp_receive $f $host"

    after [expr {$secs * 1000}] "udp_summary $f $host $secs"

    udp_send $f $host $delay
}

proc usage {} {
    puts stderr "usage: udpspeed hosts"
    exit
}

if {$argv == ""} { usage } else {
    set secs 10
    set delay 10
    set bytes 1024
    set time 1
    foreach host $argv {
	after [expr {$time * 1000}] "udp_echo $host $secs $bytes $delay"
	incr time $secs
	incr time 1
    }
}

# exit
