dad965
#!/bin/sh
dad965
#
dad965
# plugin for munin to monitor usage of unbound servers.
dad965
#
dad965
# (C) 2008 W.C.A. Wijngaards.  BSD Licensed.
dad965
#
dad965
# To install; enable statistics and unbound-control in unbound.conf
dad965
#	server:		extended-statistics: yes
dad965
#			statistics-cumulative: no
dad965
#			statistics-interval: 0
dad965
#	remote-control:	control-enable: yes
dad965
# Run the command unbound-control-setup to generate the key files.
dad965
#
dad965
# Environment variables for this script
dad965
#	statefile	- where to put temporary statefile.
dad965
#	unbound_conf	- where the unbound.conf file is located.
dad965
#	unbound_control	- where to find unbound-control executable.
dad965
#	spoof_warn	- what level to warn about spoofing
dad965
#	spoof_crit	- what level to crit about spoofing
dad965
#
dad965
# You can set them in your munin/plugin-conf.d/plugins.conf file
dad965
# with:
dad965
# [unbound*]
dad965
# user root
dad965
# env.statefile /usr/local/var/munin/plugin-state/unbound-state
dad965
# env.unbound_conf /usr/local/etc/unbound/unbound.conf
dad965
# env.unbound_control /usr/local/sbin/unbound-control
dad965
# env.spoof_warn 1000
dad965
# env.spoof_crit 100000
dad965
#
dad965
# This plugin can create different graphs depending on what name
dad965
# you link it as (with ln -s) into the plugins directory
dad965
# You can link it multiple times.
dad965
# If you are only a casual user, the _hits and _by_type are most interesting,
dad965
# possibly followed by _by_rcode.
dad965
#
dad965
#	unbound_munin_hits	- base volume, cache hits, unwanted traffic
dad965
#	unbound_munin_queue	- to monitor the internal requestlist
dad965
#	unbound_munin_memory	- memory usage
dad965
#	unbound_munin_by_type	- incoming queries by type
dad965
#	unbound_munin_by_class	- incoming queries by class
dad965
#	unbound_munin_by_opcode	- incoming queries by opcode
dad965
#	unbound_munin_by_rcode	- answers by rcode, validation status
dad965
#	unbound_munin_by_flags	- incoming queries by flags
dad965
#	unbound_munin_histogram	- histogram of query resolving times
dad965
#
dad965
# Magic markers - optional - used by installation scripts and
dad965
# munin-config:
dad965
#
dad965
#%# family=contrib
dad965
#%# capabilities=autoconf suggest
dad965
dad965
# POD documentation
dad965
: <<=cut
dad965
=head1 NAME
dad965
dad965
unbound_munin_ - Munin plugin to monitor the Unbound DNS resolver.
dad965
dad965
=head1 APPLICABLE SYSTEMS
dad965
dad965
System with unbound daemon.
dad965
dad965
=head1 CONFIGURATION
dad965
dad965
  [unbound*]
dad965
  user root
dad965
  env.statefile /var/lib/munin/plugin-state/unbound-state
dad965
  env.unbound_conf /etc/unbound/unbound.conf
dad965
  env.unbound_control /usr/sbin/unbound-control
dad965
  env.spoof_warn 1000
dad965
  env.spoof_crit 100000
dad965
dad965
Use the .env settings to override the defaults.
dad965
dad965
=head1 USAGE
dad965
dad965
Can be used to present different graphs. Use ln -s for that name in
dad965
the plugins directory to enable the graph.
dad965
unbound_munin_hits	- base volume, cache hits, unwanted traffic
dad965
unbound_munin_queue	- to monitor the internal requestlist
dad965
unbound_munin_memory	- memory usage
dad965
unbound_munin_by_type	- incoming queries by type
dad965
unbound_munin_by_class	- incoming queries by class
dad965
unbound_munin_by_opcode	- incoming queries by opcode
dad965
unbound_munin_by_rcode	- answers by rcode, validation status
dad965
unbound_munin_by_flags	- incoming queries by flags
dad965
unbound_munin_histogram - histogram of query resolving times
dad965
dad965
=head1 AUTHOR
dad965
dad965
Copyright 2008 W.C.A. Wijngaards
dad965
dad965
=head1 LICENSE
dad965
dad965
BSD
dad965
dad965
=cut
dad965
dad965
state=${statefile:-/var/lib/munin/plugin-state/unbound-state}
dad965
conf=${unbound_conf:-/etc/unbound/unbound.conf}
dad965
ctrl=${unbound_control:-/usr/sbin/unbound-control}
dad965
warn=${spoof_warn:-1000}
dad965
crit=${spoof_crit:-100000}
dad965
lock=$state.lock
dad965
dad965
# number of seconds between polling attempts.
dad965
# makes the statefile hang around for at least this many seconds,
dad965
# so that multiple links of this script can share the results.
dad965
lee=55
dad965
dad965
# to keep things within 19 characters
dad965
ABBREV="-e s/total/t/ -e s/thread/t/ -e s/num/n/ -e s/query/q/ -e s/answer/a/ -e s/unwanted/u/ -e s/requestlist/ql/ -e s/type/t/ -e s/class/c/ -e s/opcode/o/ -e s/rcode/r/ -e s/edns/e/ -e s/mem/m/ -e s/cache/c/ -e s/mod/m/"
dad965
dad965
# get value from $1 into return variable $value
dad965
get_value ( ) {
dad965
	value="`grep '^'$1'=' $state | sed -e 's/^.*=//'`"
dad965
	if test "$value"x = ""x; then
dad965
		value="0"
dad965
	fi
dad965
}
dad965
dad965
# download the state from the unbound server.
dad965
get_state ( ) {
dad965
	# obtain lock for fetching the state
dad965
	# because there is a race condition in fetching and writing to file
dad965
dad965
	# see if the lock is stale, if so, take it 
dad965
	if test -f $lock ; then
dad965
		pid="`cat $lock 2>&1`"
dad965
		kill -0 "$pid" >/dev/null 2>&1
dad965
		if test $? -ne 0 -a "$pid" != $$ ; then
dad965
			echo $$ >$lock
dad965
		fi
dad965
	fi
dad965
dad965
	i=0
dad965
	while test ! -f $lock || test "`cat $lock 2>&1`" != $$; do
dad965
		while test -f $lock; do
dad965
			# wait
dad965
			i=`expr $i + 1`
dad965
			if test $i -gt 1000; then
dad965
				sleep 1;
dad965
			fi
dad965
			if test $i -gt 1500; then
dad965
				echo "error locking $lock" "=" `cat $lock`
dad965
				rm -f $lock
dad965
				exit 1
dad965
			fi
dad965
		done
dad965
		# try to get it
dad965
		echo $$ >$lock
dad965
	done
dad965
	# do not refetch if the file exists and only LEE seconds old
dad965
	if test -f $state; then
dad965
		now=`date +%s`
dad965
		get_value "time.now"
dad965
		value="`echo $value | sed -e 's/\..*$//'`"
dad965
		if test $now -lt `expr $value + $lee`; then
dad965
			rm -f $lock
dad965
			return
dad965
		fi
dad965
	fi
dad965
	$ctrl -c $conf stats > $state
dad965
	if test $? -ne 0; then
dad965
		echo "error retrieving data from unbound server"
dad965
		rm -f $lock
dad965
		exit 1
dad965
	fi
dad965
	rm -f $lock
dad965
}
dad965
dad965
if test "$1" = "autoconf" ; then
dad965
	if test ! -f $conf; then
dad965
		echo no "($conf does not exist)"
dad965
		exit 1
dad965
	fi
dad965
	if test ! -d `dirname $state`; then
dad965
		echo no "($state directory does not exist)"
dad965
		exit 1
dad965
	fi
dad965
	echo yes
dad965
	exit 0
dad965
fi
dad965
dad965
if test "$1" = "suggest" ; then
dad965
	echo "hits"
dad965
	echo "queue"
dad965
	echo "memory"
dad965
	echo "by_type"
dad965
	echo "by_class"
dad965
	echo "by_opcode"
dad965
	echo "by_rcode"
dad965
	echo "by_flags"
dad965
	echo "histogram"
dad965
	exit 0
dad965
fi
dad965
dad965
# determine my type, by name
dad965
id=`echo $0 | sed -e 's/^.*unbound_munin_//'`
dad965
if test "$id"x = ""x; then
dad965
	# some default to keep people sane.
dad965
	id="hits"
dad965
fi
dad965
dad965
# if $1 exists in statefile, config is echoed with label $2
dad965
exist_config ( ) {
dad965
	mn=`echo $1 | sed $ABBREV | tr . _`
dad965
	if grep '^'$1'=' $state >/dev/null 2>&1; then
dad965
		echo "$mn.label $2"
dad965
		echo "$mn.min 0"
dad965
	fi
dad965
}
dad965
dad965
# print label and min 0 for a name $1 in unbound format
dad965
p_config ( ) {
dad965
	mn=`echo $1 | sed $ABBREV | tr . _`
dad965
	echo $mn.label "$2"
dad965
	echo $mn.min 0
dad965
}
dad965
dad965
if test "$1" = "config" ; then
dad965
	if test ! -f $state; then
dad965
		get_state
dad965
	fi
dad965
	case $id in
dad965
	hits)
dad965
		echo "graph_title Unbound DNS traffic and cache hits"
dad965
		echo "graph_args --base 1000 -l 0"
dad965
		echo "graph_vlabel queries / second"
dad965
		echo "graph_category DNS"
dad965
		for x in thread0.num.queries thread1.num.queries \
dad965
		thread2.num.queries thread3.num.queries thread4.num.queries \
dad965
		thread5.num.queries thread6.num.queries thread7.num.queries; do
dad965
			exist_config $x "queries handled by `basename $x .num.queries`"
dad965
		done
dad965
		p_config "total.num.queries" "total queries from clients"
dad965
		p_config "total.num.cachehits" "cache hits"
dad965
		p_config "total.num.prefetch" "cache prefetch"
dad965
		p_config "num.query.tcp" "TCP queries"
dad965
		p_config "num.query.ipv6" "IPv6 queries"
dad965
		p_config "unwanted.queries" "queries that failed acl"
dad965
		p_config "unwanted.replies" "unwanted or unsolicited replies"
dad965
		echo "u_replies.warning $warn"
dad965
		echo "u_replies.critical $crit"
dad965
		echo "graph_info DNS queries to the recursive resolver. The unwanted replies could be innocent duplicate packets, late replies, or spoof threats."
dad965
		;;
dad965
	queue)
dad965
		echo "graph_title Unbound requestlist size"
dad965
		echo "graph_args --base 1000 -l 0"
dad965
		echo "graph_vlabel number of queries"
dad965
		echo "graph_category DNS"
dad965
		p_config "total.requestlist.avg" "Average size of queue on insert"
dad965
		p_config "total.requestlist.max" "Max size of queue (in 5 min)"
dad965
		p_config "total.requestlist.overwritten" "Number of queries replaced by new ones"
dad965
		p_config "total.requestlist.exceeded" "Number of queries dropped due to lack of space"
dad965
		echo "graph_info The queries that did not hit the cache and need recursion service take up space in the requestlist. If there are too many queries, first queries get overwritten, and at last resort dropped."
dad965
		;;
dad965
	memory)
dad965
		echo "graph_title Unbound memory usage"
dad965
		echo "graph_args --base 1024 -l 0"
dad965
		echo "graph_vlabel memory used in bytes"
dad965
		echo "graph_category DNS"
dad965
		p_config "mem.total.sbrk" "Total memory"
dad965
		p_config "mem.cache.rrset" "RRset cache memory"
dad965
		p_config "mem.cache.message" "Message cache memory"
dad965
		p_config "mem.mod.iterator" "Iterator module memory"
dad965
		p_config "mem.mod.validator" "Validator module and key cache memory"
dad965
		echo "graph_info The memory used by unbound."
dad965
		;;
dad965
	by_type)
dad965
		echo "graph_title Unbound DNS queries by type"
dad965
		echo "graph_args --base 1000 -l 0"
dad965
		echo "graph_vlabel queries / second"
dad965
		echo "graph_category DNS"
dad965
		for x in `grep "^num.query.type" $state`; do
dad965
			nm=`echo $x | sed -e 's/=.*$//'`
dad965
			tp=`echo $nm | sed -e s/num.query.type.//`
dad965
			p_config "$nm" "$tp"
dad965
		done
dad965
		echo "graph_info queries by DNS RR type queried for"
dad965
		;;
dad965
	by_class)
dad965
		echo "graph_title Unbound DNS queries by class"
dad965
		echo "graph_args --base 1000 -l 0"
dad965
		echo "graph_vlabel queries / second"
dad965
		echo "graph_category DNS"
dad965
		for x in `grep "^num.query.class" $state`; do
dad965
			nm=`echo $x | sed -e 's/=.*$//'`
dad965
			tp=`echo $nm | sed -e s/num.query.class.//`
dad965
			p_config "$nm" "$tp"
dad965
		done
dad965
		echo "graph_info queries by DNS RR class queried for."
dad965
		;;
dad965
	by_opcode)
dad965
		echo "graph_title Unbound DNS queries by opcode"
dad965
		echo "graph_args --base 1000 -l 0"
dad965
		echo "graph_vlabel queries / second"
dad965
		echo "graph_category DNS"
dad965
		for x in `grep "^num.query.opcode" $state`; do
dad965
			nm=`echo $x | sed -e 's/=.*$//'`
dad965
			tp=`echo $nm | sed -e s/num.query.opcode.//`
dad965
			p_config "$nm" "$tp"
dad965
		done
dad965
		echo "graph_info queries by opcode in the query packet."
dad965
		;;
dad965
	by_rcode)
dad965
		echo "graph_title Unbound DNS answers by return code"
dad965
		echo "graph_args --base 1000 -l 0"
dad965
		echo "graph_vlabel answer packets / second"
dad965
		echo "graph_category DNS"
dad965
		for x in `grep "^num.answer.rcode" $state`; do
dad965
			nm=`echo $x | sed -e 's/=.*$//'`
dad965
			tp=`echo $nm | sed -e s/num.answer.rcode.//`
dad965
			p_config "$nm" "$tp"
dad965
		done
dad965
		p_config "num.answer.secure" "answer secure"
dad965
		p_config "num.answer.bogus" "answer bogus"
dad965
		p_config "num.rrset.bogus" "num rrsets marked bogus"
dad965
		echo "graph_info answers sorted by return value. rrsets bogus is the number of rrsets marked bogus per second by the validator"
dad965
		;;
dad965
	by_flags)
dad965
		echo "graph_title Unbound DNS incoming queries by flags"
dad965
		echo "graph_args --base 1000 -l 0"
dad965
		echo "graph_vlabel queries / second"
dad965
		echo "graph_category DNS"
dad965
		p_config "num.query.flags.QR" "QR (query reply) flag"
dad965
		p_config "num.query.flags.AA" "AA (auth answer) flag"
dad965
		p_config "num.query.flags.TC" "TC (truncated) flag"
dad965
		p_config "num.query.flags.RD" "RD (recursion desired) flag"
dad965
		p_config "num.query.flags.RA" "RA (rec avail) flag"
dad965
		p_config "num.query.flags.Z" "Z (zero) flag"
dad965
		p_config "num.query.flags.AD" "AD (auth data) flag"
dad965
		p_config "num.query.flags.CD" "CD (check disabled) flag"
dad965
		p_config "num.query.edns.present" "EDNS OPT present"
dad965
		p_config "num.query.edns.DO" "DO (DNSSEC OK) flag"
dad965
		echo "graph_info This graphs plots the flags inside incoming queries. For example, if QR, AA, TC, RA, Z flags are set, the query can be rejected. RD, AD, CD and DO are legitimately set by some software."
dad965
		;;
dad965
	histogram)
dad965
		echo "graph_title Unbound DNS histogram of reply time"
dad965
		echo "graph_args --base 1000 -l 0"
dad965
		echo "graph_vlabel queries / second"
dad965
		echo "graph_category DNS"
dad965
		echo hcache.label "cache hits"
dad965
		echo hcache.min 0
dad965
		echo hcache.draw AREA
dad965
		echo hcache.colour 999999
dad965
		echo h64ms.label "0 msec - 66 msec"
dad965
		echo h64ms.min 0
dad965
		echo h64ms.draw STACK
dad965
		echo h64ms.colour 0000FF
dad965
		echo h128ms.label "66 msec - 131 msec"
dad965
		echo h128ms.min 0
dad965
		echo h128ms.colour 1F00DF
dad965
		echo h128ms.draw STACK
dad965
		echo h256ms.label "131 msec - 262 msec"
dad965
		echo h256ms.min 0
dad965
		echo h256ms.draw STACK
dad965
		echo h256ms.colour 3F00BF
dad965
		echo h512ms.label "262 msec - 524 msec"
dad965
		echo h512ms.min 0
dad965
		echo h512ms.draw STACK
dad965
		echo h512ms.colour 5F009F
dad965
		echo h1s.label "524 msec - 1 sec"
dad965
		echo h1s.min 0
dad965
		echo h1s.draw STACK
dad965
		echo h1s.colour 7F007F
dad965
		echo h2s.label "1 sec - 2 sec"
dad965
		echo h2s.min 0
dad965
		echo h2s.draw STACK
dad965
		echo h2s.colour 9F005F
dad965
		echo h4s.label "2 sec - 4 sec"
dad965
		echo h4s.min 0
dad965
		echo h4s.draw STACK
dad965
		echo h4s.colour BF003F
dad965
		echo h8s.label "4 sec - 8 sec"
dad965
		echo h8s.min 0
dad965
		echo h8s.draw STACK
dad965
		echo h8s.colour DF001F
dad965
		echo h16s.label "8 sec - ..."
dad965
		echo h16s.min 0
dad965
		echo h16s.draw STACK
dad965
		echo h16s.colour FF0000
dad965
		echo "graph_info Histogram of the reply times for queries."
dad965
		;;
dad965
	esac
dad965
dad965
	exit 0
dad965
fi
dad965
dad965
# do the stats itself
dad965
get_state
dad965
dad965
# get the time elapsed
dad965
get_value "time.elapsed"
dad965
if test $value = 0 || test $value = "0.000000"; then
dad965
	echo "error: time elapsed 0 or could not retrieve data"
dad965
	exit 1
dad965
fi
dad965
elapsed="$value"
dad965
dad965
# print value for $1 / elapsed
dad965
print_qps ( ) {
dad965
	mn=`echo $1 | sed $ABBREV | tr . _`
dad965
	get_value $1
dad965
	echo "$mn.value" `echo scale=6';' $value / $elapsed | bc `
dad965
}
dad965
dad965
# print qps if line already found in $2
dad965
print_qps_line ( ) {
dad965
	mn=`echo $1 | sed $ABBREV | tr . _`
dad965
	value="`echo $2 | sed -e 's/^.*=//'`"
dad965
	echo "$mn.value" `echo scale=6';' $value / $elapsed | bc `
dad965
}
dad965
dad965
# print value for $1
dad965
print_value ( ) {
dad965
	mn=`echo $1 | sed $ABBREV | tr . _`
dad965
	get_value $1
dad965
	echo "$mn.value" $value
dad965
}
dad965
dad965
case $id in
dad965
hits)
dad965
	for x in thread0.num.queries thread1.num.queries thread2.num.queries \
dad965
		thread3.num.queries thread4.num.queries thread5.num.queries \
dad965
		thread6.num.queries thread7.num.queries total.num.queries \
dad965
		total.num.cachehits total.num.prefetch num.query.tcp \
dad965
		num.query.ipv6 unwanted.queries unwanted.replies; do
dad965
		if grep "^"$x"=" $state >/dev/null 2>&1; then
dad965
			print_qps $x
dad965
		fi
dad965
	done
dad965
	;;
dad965
queue)
dad965
	for x in total.requestlist.avg total.requestlist.max \
dad965
		total.requestlist.overwritten total.requestlist.exceeded; do
dad965
		print_value $x
dad965
	done
dad965
	;;
dad965
memory)
dad965
	mn=`echo mem.total.sbrk | sed $ABBREV | tr . _`
dad965
	get_value 'mem.total.sbrk'
dad965
	if test $value -eq 0; then
dad965
		chk=`echo $ctrl | sed -e 's/-control$/-checkconf/'`
dad965
		pidf=`$chk -o pidfile $conf 2>&1`
dad965
		pid=`cat $pidf 2>&1`
dad965
		value=`ps -p "$pid" -o rss= 2>&1`
dad965
		if test "`expr $value + 1 - 1 2>&1`" -eq "$value" 2>&1; then
dad965
			value=`expr $value \* 1024` 
dad965
		else
dad965
			value=0
dad965
		fi
dad965
	fi
dad965
	echo "$mn.value" $value
dad965
	for x in mem.cache.rrset mem.cache.message \
dad965
		mem.mod.iterator mem.mod.validator; do
dad965
		print_value $x
dad965
	done
dad965
	;;
dad965
by_type)
dad965
	for x in `grep "^num.query.type" $state`; do
dad965
		nm=`echo $x | sed -e 's/=.*$//'`
dad965
		print_qps_line $nm $x
dad965
	done
dad965
	;;
dad965
by_class)
dad965
	for x in `grep "^num.query.class" $state`; do
dad965
		nm=`echo $x | sed -e 's/=.*$//'`
dad965
		print_qps_line $nm $x
dad965
	done
dad965
	;;
dad965
by_opcode)
dad965
	for x in `grep "^num.query.opcode" $state`; do
dad965
		nm=`echo $x | sed -e 's/=.*$//'`
dad965
		print_qps_line $nm $x
dad965
	done
dad965
	;;
dad965
by_rcode)
dad965
	for x in `grep "^num.answer.rcode" $state`; do
dad965
		nm=`echo $x | sed -e 's/=.*$//'`
dad965
		print_qps_line $nm $x
dad965
	done
dad965
	print_qps "num.answer.secure"
dad965
	print_qps "num.answer.bogus"
dad965
	print_qps "num.rrset.bogus"
dad965
	;;
dad965
by_flags)
dad965
	for x in num.query.flags.QR num.query.flags.AA num.query.flags.TC num.query.flags.RD num.query.flags.RA num.query.flags.Z num.query.flags.AD num.query.flags.CD num.query.edns.present num.query.edns.DO; do
dad965
		print_qps $x
dad965
	done
dad965
	;;
dad965
histogram)
dad965
	get_value total.num.cachehits
dad965
	echo hcache.value `echo scale=6';' $value / $elapsed | bc `
dad965
	r=0
dad965
	for x in histogram.000000.000000.to.000000.000001 \
dad965
		histogram.000000.000001.to.000000.000002 \
dad965
		histogram.000000.000002.to.000000.000004 \
dad965
		histogram.000000.000004.to.000000.000008 \
dad965
		histogram.000000.000008.to.000000.000016 \
dad965
		histogram.000000.000016.to.000000.000032 \
dad965
		histogram.000000.000032.to.000000.000064 \
dad965
		histogram.000000.000064.to.000000.000128 \
dad965
		histogram.000000.000128.to.000000.000256 \
dad965
		histogram.000000.000256.to.000000.000512 \
dad965
		histogram.000000.000512.to.000000.001024 \
dad965
		histogram.000000.001024.to.000000.002048 \
dad965
		histogram.000000.002048.to.000000.004096 \
dad965
		histogram.000000.004096.to.000000.008192 \
dad965
		histogram.000000.008192.to.000000.016384 \
dad965
		histogram.000000.016384.to.000000.032768 \
dad965
		histogram.000000.032768.to.000000.065536; do
dad965
		get_value $x
dad965
		r=`expr $r + $value`
dad965
	done
dad965
	echo h64ms.value `echo scale=6';' $r / $elapsed | bc `
dad965
	get_value histogram.000000.065536.to.000000.131072
dad965
	echo h128ms.value `echo scale=6';' $value / $elapsed | bc `
dad965
	get_value histogram.000000.131072.to.000000.262144
dad965
	echo h256ms.value `echo scale=6';' $value / $elapsed | bc `
dad965
	get_value histogram.000000.262144.to.000000.524288
dad965
	echo h512ms.value `echo scale=6';' $value / $elapsed | bc `
dad965
	get_value histogram.000000.524288.to.000001.000000
dad965
	echo h1s.value `echo scale=6';' $value / $elapsed | bc `
dad965
	get_value histogram.000001.000000.to.000002.000000
dad965
	echo h2s.value `echo scale=6';' $value / $elapsed | bc `
dad965
	get_value histogram.000002.000000.to.000004.000000
dad965
	echo h4s.value `echo scale=6';' $value / $elapsed | bc `
dad965
	get_value histogram.000004.000000.to.000008.000000
dad965
	echo h8s.value `echo scale=6';' $value / $elapsed | bc `
dad965
	r=0
dad965
	for x in histogram.000008.000000.to.000016.000000 \
dad965
		histogram.000016.000000.to.000032.000000 \
dad965
		histogram.000032.000000.to.000064.000000 \
dad965
		histogram.000064.000000.to.000128.000000 \
dad965
		histogram.000128.000000.to.000256.000000 \
dad965
		histogram.000256.000000.to.000512.000000 \
dad965
		histogram.000512.000000.to.001024.000000 \
dad965
		histogram.001024.000000.to.002048.000000 \
dad965
		histogram.002048.000000.to.004096.000000 \
dad965
		histogram.004096.000000.to.008192.000000 \
dad965
		histogram.008192.000000.to.016384.000000 \
dad965
		histogram.016384.000000.to.032768.000000 \
dad965
		histogram.032768.000000.to.065536.000000 \
dad965
		histogram.065536.000000.to.131072.000000 \
dad965
		histogram.131072.000000.to.262144.000000 \
dad965
		histogram.262144.000000.to.524288.000000; do
dad965
		get_value $x
dad965
		r=`expr $r + $value`
dad965
	done
dad965
	echo h16s.value `echo scale=6';' $r / $elapsed | bc `
dad965
	;;
dad965
esac