Home | History | Annotate | Line # | Download | only in contrib
unbound_munin_ revision 1.1.1.1.2.2
      1  1.1.1.1.2.2  pgoyette #!/bin/sh
      2  1.1.1.1.2.2  pgoyette #
      3  1.1.1.1.2.2  pgoyette # plugin for munin to monitor usage of unbound servers.
      4  1.1.1.1.2.2  pgoyette # To install copy this to /usr/local/share/munin/plugins/unbound_munin_
      5  1.1.1.1.2.2  pgoyette # and use munin-node-configure (--suggest, --shell).
      6  1.1.1.1.2.2  pgoyette #
      7  1.1.1.1.2.2  pgoyette # (C) 2008 W.C.A. Wijngaards.  BSD Licensed.
      8  1.1.1.1.2.2  pgoyette #
      9  1.1.1.1.2.2  pgoyette # To install; enable statistics and unbound-control in unbound.conf
     10  1.1.1.1.2.2  pgoyette #	server:		extended-statistics: yes
     11  1.1.1.1.2.2  pgoyette #			statistics-cumulative: no
     12  1.1.1.1.2.2  pgoyette #			statistics-interval: 0
     13  1.1.1.1.2.2  pgoyette #	remote-control:	control-enable: yes
     14  1.1.1.1.2.2  pgoyette # Run the command unbound-control-setup to generate the key files.
     15  1.1.1.1.2.2  pgoyette #
     16  1.1.1.1.2.2  pgoyette # Environment variables for this script
     17  1.1.1.1.2.2  pgoyette #	statefile	- where to put temporary statefile.
     18  1.1.1.1.2.2  pgoyette #	unbound_conf	- where the unbound.conf file is located.
     19  1.1.1.1.2.2  pgoyette #	unbound_control	- where to find unbound-control executable.
     20  1.1.1.1.2.2  pgoyette #	spoof_warn	- what level to warn about spoofing
     21  1.1.1.1.2.2  pgoyette #	spoof_crit	- what level to crit about spoofing
     22  1.1.1.1.2.2  pgoyette #
     23  1.1.1.1.2.2  pgoyette # You can set them in your munin/plugin-conf.d/plugins.conf file
     24  1.1.1.1.2.2  pgoyette # with:
     25  1.1.1.1.2.2  pgoyette # [unbound*]
     26  1.1.1.1.2.2  pgoyette # user root
     27  1.1.1.1.2.2  pgoyette # env.statefile /usr/local/var/munin/plugin-state/unbound-state
     28  1.1.1.1.2.2  pgoyette # env.unbound_conf /usr/local/etc/unbound/unbound.conf
     29  1.1.1.1.2.2  pgoyette # env.unbound_control /usr/local/sbin/unbound-control
     30  1.1.1.1.2.2  pgoyette # env.spoof_warn 1000
     31  1.1.1.1.2.2  pgoyette # env.spoof_crit 100000
     32  1.1.1.1.2.2  pgoyette #
     33  1.1.1.1.2.2  pgoyette # This plugin can create different graphs depending on what name
     34  1.1.1.1.2.2  pgoyette # you link it as (with ln -s) into the plugins directory
     35  1.1.1.1.2.2  pgoyette # You can link it multiple times.
     36  1.1.1.1.2.2  pgoyette # If you are only a casual user, the _hits and _by_type are most interesting,
     37  1.1.1.1.2.2  pgoyette # possibly followed by _by_rcode.
     38  1.1.1.1.2.2  pgoyette #
     39  1.1.1.1.2.2  pgoyette #	unbound_munin_hits	- base volume, cache hits, unwanted traffic
     40  1.1.1.1.2.2  pgoyette #	unbound_munin_queue	- to monitor the internal requestlist
     41  1.1.1.1.2.2  pgoyette #	unbound_munin_memory	- memory usage
     42  1.1.1.1.2.2  pgoyette #	unbound_munin_by_type	- incoming queries by type
     43  1.1.1.1.2.2  pgoyette #	unbound_munin_by_class	- incoming queries by class
     44  1.1.1.1.2.2  pgoyette #	unbound_munin_by_opcode	- incoming queries by opcode
     45  1.1.1.1.2.2  pgoyette #	unbound_munin_by_rcode	- answers by rcode, validation status
     46  1.1.1.1.2.2  pgoyette #	unbound_munin_by_flags	- incoming queries by flags
     47  1.1.1.1.2.2  pgoyette #	unbound_munin_histogram	- histogram of query resolving times
     48  1.1.1.1.2.2  pgoyette #
     49  1.1.1.1.2.2  pgoyette # Magic markers - optional - used by installation scripts and
     50  1.1.1.1.2.2  pgoyette # munin-config:  (originally contrib family but munin-node-configure ignores it)
     51  1.1.1.1.2.2  pgoyette #
     52  1.1.1.1.2.2  pgoyette #%# family=auto
     53  1.1.1.1.2.2  pgoyette #%# capabilities=autoconf suggest
     54  1.1.1.1.2.2  pgoyette 
     55  1.1.1.1.2.2  pgoyette # POD documentation
     56  1.1.1.1.2.2  pgoyette : <<=cut
     57  1.1.1.1.2.2  pgoyette =head1 NAME
     58  1.1.1.1.2.2  pgoyette 
     59  1.1.1.1.2.2  pgoyette unbound_munin_ - Munin plugin to monitor the Unbound DNS resolver.
     60  1.1.1.1.2.2  pgoyette 
     61  1.1.1.1.2.2  pgoyette =head1 APPLICABLE SYSTEMS
     62  1.1.1.1.2.2  pgoyette 
     63  1.1.1.1.2.2  pgoyette System with unbound daemon.
     64  1.1.1.1.2.2  pgoyette 
     65  1.1.1.1.2.2  pgoyette =head1 CONFIGURATION
     66  1.1.1.1.2.2  pgoyette 
     67  1.1.1.1.2.2  pgoyette   [unbound*]
     68  1.1.1.1.2.2  pgoyette   user root
     69  1.1.1.1.2.2  pgoyette   env.statefile /usr/local/var/munin/plugin-state/unbound-state
     70  1.1.1.1.2.2  pgoyette   env.unbound_conf /usr/local/etc/unbound/unbound.conf
     71  1.1.1.1.2.2  pgoyette   env.unbound_control /usr/local/sbin/unbound-control
     72  1.1.1.1.2.2  pgoyette   env.spoof_warn 1000
     73  1.1.1.1.2.2  pgoyette   env.spoof_crit 100000
     74  1.1.1.1.2.2  pgoyette 
     75  1.1.1.1.2.2  pgoyette Use the .env settings to override the defaults.
     76  1.1.1.1.2.2  pgoyette 
     77  1.1.1.1.2.2  pgoyette =head1 USAGE
     78  1.1.1.1.2.2  pgoyette 
     79  1.1.1.1.2.2  pgoyette Can be used to present different graphs. Use ln -s for that name in
     80  1.1.1.1.2.2  pgoyette the plugins directory to enable the graph.
     81  1.1.1.1.2.2  pgoyette unbound_munin_hits	- base volume, cache hits, unwanted traffic
     82  1.1.1.1.2.2  pgoyette unbound_munin_queue	- to monitor the internal requestlist
     83  1.1.1.1.2.2  pgoyette unbound_munin_memory	- memory usage
     84  1.1.1.1.2.2  pgoyette unbound_munin_by_type	- incoming queries by type
     85  1.1.1.1.2.2  pgoyette unbound_munin_by_class	- incoming queries by class
     86  1.1.1.1.2.2  pgoyette unbound_munin_by_opcode	- incoming queries by opcode
     87  1.1.1.1.2.2  pgoyette unbound_munin_by_rcode	- answers by rcode, validation status
     88  1.1.1.1.2.2  pgoyette unbound_munin_by_flags	- incoming queries by flags
     89  1.1.1.1.2.2  pgoyette unbound_munin_histogram - histogram of query resolving times
     90  1.1.1.1.2.2  pgoyette 
     91  1.1.1.1.2.2  pgoyette =head1 AUTHOR
     92  1.1.1.1.2.2  pgoyette 
     93  1.1.1.1.2.2  pgoyette Copyright 2008 W.C.A. Wijngaards
     94  1.1.1.1.2.2  pgoyette 
     95  1.1.1.1.2.2  pgoyette =head1 LICENSE
     96  1.1.1.1.2.2  pgoyette 
     97  1.1.1.1.2.2  pgoyette BSD
     98  1.1.1.1.2.2  pgoyette 
     99  1.1.1.1.2.2  pgoyette =cut
    100  1.1.1.1.2.2  pgoyette 
    101  1.1.1.1.2.2  pgoyette state=${statefile:-/usr/local/var/munin/plugin-state/unbound-state}
    102  1.1.1.1.2.2  pgoyette conf=${unbound_conf:-/usr/local/etc/unbound/unbound.conf}
    103  1.1.1.1.2.2  pgoyette ctrl=${unbound_control:-/usr/local/sbin/unbound-control}
    104  1.1.1.1.2.2  pgoyette warn=${spoof_warn:-1000}
    105  1.1.1.1.2.2  pgoyette crit=${spoof_crit:-100000}
    106  1.1.1.1.2.2  pgoyette lock=$state.lock
    107  1.1.1.1.2.2  pgoyette 
    108  1.1.1.1.2.2  pgoyette # number of seconds between polling attempts.
    109  1.1.1.1.2.2  pgoyette # makes the statefile hang around for at least this many seconds,
    110  1.1.1.1.2.2  pgoyette # so that multiple links of this script can share the results.
    111  1.1.1.1.2.2  pgoyette lee=55
    112  1.1.1.1.2.2  pgoyette 
    113  1.1.1.1.2.2  pgoyette # to keep things within 19 characters
    114  1.1.1.1.2.2  pgoyette 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/"
    115  1.1.1.1.2.2  pgoyette 
    116  1.1.1.1.2.2  pgoyette # get value from $1 into return variable $value
    117  1.1.1.1.2.2  pgoyette get_value ( ) {
    118  1.1.1.1.2.2  pgoyette 	value="`grep '^'$1'=' $state | sed -e 's/^.*=//'`"
    119  1.1.1.1.2.2  pgoyette 	if test "$value"x = ""x; then
    120  1.1.1.1.2.2  pgoyette 		value="0"
    121  1.1.1.1.2.2  pgoyette 	fi
    122  1.1.1.1.2.2  pgoyette }
    123  1.1.1.1.2.2  pgoyette 
    124  1.1.1.1.2.2  pgoyette # download the state from the unbound server.
    125  1.1.1.1.2.2  pgoyette get_state ( ) {
    126  1.1.1.1.2.2  pgoyette 	# obtain lock for fetching the state
    127  1.1.1.1.2.2  pgoyette 	# because there is a race condition in fetching and writing to file
    128  1.1.1.1.2.2  pgoyette 
    129  1.1.1.1.2.2  pgoyette 	# see if the lock is stale, if so, take it 
    130  1.1.1.1.2.2  pgoyette 	if test -f $lock ; then
    131  1.1.1.1.2.2  pgoyette 		pid="`cat $lock 2>&1`"
    132  1.1.1.1.2.2  pgoyette 		kill -0 "$pid" >/dev/null 2>&1
    133  1.1.1.1.2.2  pgoyette 		if test $? -ne 0 -a "$pid" != $$ ; then
    134  1.1.1.1.2.2  pgoyette 			echo $$ >$lock
    135  1.1.1.1.2.2  pgoyette 		fi
    136  1.1.1.1.2.2  pgoyette 	fi
    137  1.1.1.1.2.2  pgoyette 
    138  1.1.1.1.2.2  pgoyette 	i=0
    139  1.1.1.1.2.2  pgoyette 	while test ! -f $lock || test "`cat $lock 2>&1`" != $$; do
    140  1.1.1.1.2.2  pgoyette 		while test -f $lock; do
    141  1.1.1.1.2.2  pgoyette 			# wait
    142  1.1.1.1.2.2  pgoyette 			i=`expr $i + 1`
    143  1.1.1.1.2.2  pgoyette 			if test $i -gt 1000; then
    144  1.1.1.1.2.2  pgoyette 				sleep 1;
    145  1.1.1.1.2.2  pgoyette 			fi
    146  1.1.1.1.2.2  pgoyette 			if test $i -gt 1500; then
    147  1.1.1.1.2.2  pgoyette 				echo "error locking $lock" "=" `cat $lock`
    148  1.1.1.1.2.2  pgoyette 				rm -f $lock
    149  1.1.1.1.2.2  pgoyette 				exit 1
    150  1.1.1.1.2.2  pgoyette 			fi
    151  1.1.1.1.2.2  pgoyette 		done
    152  1.1.1.1.2.2  pgoyette 		# try to get it
    153  1.1.1.1.2.2  pgoyette 		echo $$ >$lock
    154  1.1.1.1.2.2  pgoyette 	done
    155  1.1.1.1.2.2  pgoyette 	# do not refetch if the file exists and only LEE seconds old
    156  1.1.1.1.2.2  pgoyette 	if test -f $state; then
    157  1.1.1.1.2.2  pgoyette 		now=`date +%s`
    158  1.1.1.1.2.2  pgoyette 		get_value "time.now"
    159  1.1.1.1.2.2  pgoyette 		value="`echo $value | sed -e 's/\..*$//'`"
    160  1.1.1.1.2.2  pgoyette 		if test $now -lt `expr $value + $lee`; then
    161  1.1.1.1.2.2  pgoyette 			rm -f $lock
    162  1.1.1.1.2.2  pgoyette 			return
    163  1.1.1.1.2.2  pgoyette 		fi
    164  1.1.1.1.2.2  pgoyette 	fi
    165  1.1.1.1.2.2  pgoyette 	$ctrl -c $conf stats > $state
    166  1.1.1.1.2.2  pgoyette 	if test $? -ne 0; then
    167  1.1.1.1.2.2  pgoyette 		echo "error retrieving data from unbound server"
    168  1.1.1.1.2.2  pgoyette 		rm -f $lock
    169  1.1.1.1.2.2  pgoyette 		exit 1
    170  1.1.1.1.2.2  pgoyette 	fi
    171  1.1.1.1.2.2  pgoyette 	rm -f $lock
    172  1.1.1.1.2.2  pgoyette }
    173  1.1.1.1.2.2  pgoyette 
    174  1.1.1.1.2.2  pgoyette if test "$1" = "autoconf" ; then
    175  1.1.1.1.2.2  pgoyette 	if test ! -f $conf; then
    176  1.1.1.1.2.2  pgoyette 		echo no "($conf does not exist)"
    177  1.1.1.1.2.2  pgoyette 		exit 1
    178  1.1.1.1.2.2  pgoyette 	fi
    179  1.1.1.1.2.2  pgoyette 	if test ! -d `dirname $state`; then
    180  1.1.1.1.2.2  pgoyette 		echo no "(`dirname $state` directory does not exist)"
    181  1.1.1.1.2.2  pgoyette 		exit 1
    182  1.1.1.1.2.2  pgoyette 	fi
    183  1.1.1.1.2.2  pgoyette 	echo yes
    184  1.1.1.1.2.2  pgoyette 	exit 0
    185  1.1.1.1.2.2  pgoyette fi
    186  1.1.1.1.2.2  pgoyette 
    187  1.1.1.1.2.2  pgoyette if test "$1" = "suggest" ; then
    188  1.1.1.1.2.2  pgoyette 	echo "hits"
    189  1.1.1.1.2.2  pgoyette 	echo "queue"
    190  1.1.1.1.2.2  pgoyette 	echo "memory"
    191  1.1.1.1.2.2  pgoyette 	echo "by_type"
    192  1.1.1.1.2.2  pgoyette 	echo "by_class"
    193  1.1.1.1.2.2  pgoyette 	echo "by_opcode"
    194  1.1.1.1.2.2  pgoyette 	echo "by_rcode"
    195  1.1.1.1.2.2  pgoyette 	echo "by_flags"
    196  1.1.1.1.2.2  pgoyette 	echo "histogram"
    197  1.1.1.1.2.2  pgoyette 	exit 0
    198  1.1.1.1.2.2  pgoyette fi
    199  1.1.1.1.2.2  pgoyette 
    200  1.1.1.1.2.2  pgoyette # determine my type, by name
    201  1.1.1.1.2.2  pgoyette id=`echo $0 | sed -e 's/^.*unbound_munin_//'`
    202  1.1.1.1.2.2  pgoyette if test "$id"x = ""x; then
    203  1.1.1.1.2.2  pgoyette 	# some default to keep people sane.
    204  1.1.1.1.2.2  pgoyette 	id="hits"
    205  1.1.1.1.2.2  pgoyette fi
    206  1.1.1.1.2.2  pgoyette 
    207  1.1.1.1.2.2  pgoyette # if $1 exists in statefile, config is echoed with label $2
    208  1.1.1.1.2.2  pgoyette exist_config ( ) {
    209  1.1.1.1.2.2  pgoyette 	mn=`echo $1 | sed $ABBREV | tr . _`
    210  1.1.1.1.2.2  pgoyette 	if grep '^'$1'=' $state >/dev/null 2>&1; then
    211  1.1.1.1.2.2  pgoyette 		echo "$mn.label $2"
    212  1.1.1.1.2.2  pgoyette 		echo "$mn.min 0"
    213  1.1.1.1.2.2  pgoyette 		echo "$mn.type ABSOLUTE"
    214  1.1.1.1.2.2  pgoyette 	fi
    215  1.1.1.1.2.2  pgoyette }
    216  1.1.1.1.2.2  pgoyette 
    217  1.1.1.1.2.2  pgoyette # print label and min 0 for a name $1 in unbound format
    218  1.1.1.1.2.2  pgoyette p_config ( ) {
    219  1.1.1.1.2.2  pgoyette 	mn=`echo $1 | sed $ABBREV | tr . _`
    220  1.1.1.1.2.2  pgoyette 	echo $mn.label "$2"
    221  1.1.1.1.2.2  pgoyette 	echo $mn.min 0
    222  1.1.1.1.2.2  pgoyette 	echo $mn.type $3
    223  1.1.1.1.2.2  pgoyette }
    224  1.1.1.1.2.2  pgoyette 
    225  1.1.1.1.2.2  pgoyette if test "$1" = "config" ; then
    226  1.1.1.1.2.2  pgoyette 	if test ! -f $state; then
    227  1.1.1.1.2.2  pgoyette 		get_state
    228  1.1.1.1.2.2  pgoyette 	fi
    229  1.1.1.1.2.2  pgoyette 	case $id in
    230  1.1.1.1.2.2  pgoyette 	hits)
    231  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound DNS traffic and cache hits"
    232  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1000 -l 0"
    233  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel queries / \${graph_period}"
    234  1.1.1.1.2.2  pgoyette 		echo "graph_scale no"
    235  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    236  1.1.1.1.2.2  pgoyette 		for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
    237  1.1.1.1.2.2  pgoyette 			sed -e 's/=.*//'`; do
    238  1.1.1.1.2.2  pgoyette 			exist_config $x "queries handled by `basename $x .num.queries`"
    239  1.1.1.1.2.2  pgoyette 		done
    240  1.1.1.1.2.2  pgoyette 		p_config "total.num.queries" "total queries from clients" "ABSOLUTE"
    241  1.1.1.1.2.2  pgoyette 		p_config "total.num.cachehits" "cache hits" "ABSOLUTE"
    242  1.1.1.1.2.2  pgoyette 		p_config "total.num.prefetch" "cache prefetch" "ABSOLUTE"
    243  1.1.1.1.2.2  pgoyette 		p_config "num.query.tcp" "TCP queries" "ABSOLUTE"
    244  1.1.1.1.2.2  pgoyette 		p_config "num.query.tcpout" "TCP out queries" "ABSOLUTE"
    245  1.1.1.1.2.2  pgoyette 		p_config "num.query.ipv6" "IPv6 queries" "ABSOLUTE"
    246  1.1.1.1.2.2  pgoyette 		p_config "unwanted.queries" "queries that failed acl" "ABSOLUTE"
    247  1.1.1.1.2.2  pgoyette 		p_config "unwanted.replies" "unwanted or unsolicited replies" "ABSOLUTE"
    248  1.1.1.1.2.2  pgoyette 		echo "u_replies.warning $warn"
    249  1.1.1.1.2.2  pgoyette 		echo "u_replies.critical $crit"
    250  1.1.1.1.2.2  pgoyette 		echo "graph_info DNS queries to the recursive resolver. The unwanted replies could be innocent duplicate packets, late replies, or spoof threats."
    251  1.1.1.1.2.2  pgoyette 		;;
    252  1.1.1.1.2.2  pgoyette 	queue)
    253  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound requestlist size"
    254  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1000 -l 0"
    255  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel number of queries"
    256  1.1.1.1.2.2  pgoyette 		echo "graph_scale no"
    257  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    258  1.1.1.1.2.2  pgoyette 		p_config "total.requestlist.avg" "Average size of queue on insert" "GAUGE"
    259  1.1.1.1.2.2  pgoyette 		p_config "total.requestlist.max" "Max size of queue (in 5 min)" "GAUGE"
    260  1.1.1.1.2.2  pgoyette 		p_config "total.requestlist.overwritten" "Number of queries replaced by new ones" "GAUGE"
    261  1.1.1.1.2.2  pgoyette 		p_config "total.requestlist.exceeded" "Number of queries dropped due to lack of space" "GAUGE"
    262  1.1.1.1.2.2  pgoyette 		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."
    263  1.1.1.1.2.2  pgoyette 		;;
    264  1.1.1.1.2.2  pgoyette 	memory)
    265  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound memory usage"
    266  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1024 -l 0"
    267  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel memory used in bytes"
    268  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    269  1.1.1.1.2.2  pgoyette 		p_config "mem.total.sbrk" "Total memory" "GAUGE"
    270  1.1.1.1.2.2  pgoyette 		p_config "mem.cache.rrset" "RRset cache memory" "GAUGE"
    271  1.1.1.1.2.2  pgoyette 		p_config "mem.cache.message" "Message cache memory" "GAUGE"
    272  1.1.1.1.2.2  pgoyette 		p_config "mem.mod.iterator" "Iterator module memory" "GAUGE"
    273  1.1.1.1.2.2  pgoyette 		p_config "mem.mod.validator" "Validator module and key cache memory" "GAUGE"
    274  1.1.1.1.2.2  pgoyette 		p_config "msg.cache.count" "msg cache count" "GAUGE"
    275  1.1.1.1.2.2  pgoyette 		p_config "rrset.cache.count" "rrset cache count" "GAUGE"
    276  1.1.1.1.2.2  pgoyette 		p_config "infra.cache.count" "infra cache count" "GAUGE"
    277  1.1.1.1.2.2  pgoyette 		p_config "key.cache.count" "key cache count" "GAUGE"
    278  1.1.1.1.2.2  pgoyette 		echo "graph_info The memory used by unbound."
    279  1.1.1.1.2.2  pgoyette 		;;
    280  1.1.1.1.2.2  pgoyette 	by_type)
    281  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound DNS queries by type"
    282  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1000 -l 0"
    283  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel queries / \${graph_period}"
    284  1.1.1.1.2.2  pgoyette 		echo "graph_scale no"
    285  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    286  1.1.1.1.2.2  pgoyette 		for x in `grep "^num.query.type" $state`; do
    287  1.1.1.1.2.2  pgoyette 			nm=`echo $x | sed -e 's/=.*$//'`
    288  1.1.1.1.2.2  pgoyette 			tp=`echo $nm | sed -e s/num.query.type.//`
    289  1.1.1.1.2.2  pgoyette 			p_config "$nm" "$tp" "ABSOLUTE"
    290  1.1.1.1.2.2  pgoyette 		done
    291  1.1.1.1.2.2  pgoyette 		echo "graph_info queries by DNS RR type queried for"
    292  1.1.1.1.2.2  pgoyette 		;;
    293  1.1.1.1.2.2  pgoyette 	by_class)
    294  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound DNS queries by class"
    295  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1000 -l 0"
    296  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel queries / \${graph_period}"
    297  1.1.1.1.2.2  pgoyette 		echo "graph_scale no"
    298  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    299  1.1.1.1.2.2  pgoyette 		for x in `grep "^num.query.class" $state`; do
    300  1.1.1.1.2.2  pgoyette 			nm=`echo $x | sed -e 's/=.*$//'`
    301  1.1.1.1.2.2  pgoyette 			tp=`echo $nm | sed -e s/num.query.class.//`
    302  1.1.1.1.2.2  pgoyette 			p_config "$nm" "$tp" "ABSOLUTE"
    303  1.1.1.1.2.2  pgoyette 		done
    304  1.1.1.1.2.2  pgoyette 		echo "graph_info queries by DNS RR class queried for."
    305  1.1.1.1.2.2  pgoyette 		;;
    306  1.1.1.1.2.2  pgoyette 	by_opcode)
    307  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound DNS queries by opcode"
    308  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1000 -l 0"
    309  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel queries / \${graph_period}"
    310  1.1.1.1.2.2  pgoyette 		echo "graph_scale no"
    311  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    312  1.1.1.1.2.2  pgoyette 		for x in `grep "^num.query.opcode" $state`; do
    313  1.1.1.1.2.2  pgoyette 			nm=`echo $x | sed -e 's/=.*$//'`
    314  1.1.1.1.2.2  pgoyette 			tp=`echo $nm | sed -e s/num.query.opcode.//`
    315  1.1.1.1.2.2  pgoyette 			p_config "$nm" "$tp" "ABSOLUTE"
    316  1.1.1.1.2.2  pgoyette 		done
    317  1.1.1.1.2.2  pgoyette 		echo "graph_info queries by opcode in the query packet."
    318  1.1.1.1.2.2  pgoyette 		;;
    319  1.1.1.1.2.2  pgoyette 	by_rcode)
    320  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound DNS answers by return code"
    321  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1000 -l 0"
    322  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel answer packets / \${graph_period}"
    323  1.1.1.1.2.2  pgoyette 		echo "graph_scale no"
    324  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    325  1.1.1.1.2.2  pgoyette 		for x in `grep "^num.answer.rcode" $state`; do
    326  1.1.1.1.2.2  pgoyette 			nm=`echo $x | sed -e 's/=.*$//'`
    327  1.1.1.1.2.2  pgoyette 			tp=`echo $nm | sed -e s/num.answer.rcode.//`
    328  1.1.1.1.2.2  pgoyette 			p_config "$nm" "$tp" "ABSOLUTE"
    329  1.1.1.1.2.2  pgoyette 		done
    330  1.1.1.1.2.2  pgoyette 		p_config "num.answer.secure" "answer secure" "ABSOLUTE"
    331  1.1.1.1.2.2  pgoyette 		p_config "num.answer.bogus" "answer bogus" "ABSOLUTE"
    332  1.1.1.1.2.2  pgoyette 		p_config "num.rrset.bogus" "num rrsets marked bogus" "ABSOLUTE"
    333  1.1.1.1.2.2  pgoyette 		echo "graph_info answers sorted by return value. rrsets bogus is the number of rrsets marked bogus per \${graph_period} by the validator"
    334  1.1.1.1.2.2  pgoyette 		;;
    335  1.1.1.1.2.2  pgoyette 	by_flags)
    336  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound DNS incoming queries by flags"
    337  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1000 -l 0"
    338  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel queries / \${graph_period}"
    339  1.1.1.1.2.2  pgoyette 		echo "graph_scale no"
    340  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    341  1.1.1.1.2.2  pgoyette 		p_config "num.query.flags.QR" "QR (query reply) flag" "ABSOLUTE"
    342  1.1.1.1.2.2  pgoyette 		p_config "num.query.flags.AA" "AA (auth answer) flag" "ABSOLUTE"
    343  1.1.1.1.2.2  pgoyette 		p_config "num.query.flags.TC" "TC (truncated) flag" "ABSOLUTE"
    344  1.1.1.1.2.2  pgoyette 		p_config "num.query.flags.RD" "RD (recursion desired) flag" "ABSOLUTE"
    345  1.1.1.1.2.2  pgoyette 		p_config "num.query.flags.RA" "RA (rec avail) flag" "ABSOLUTE"
    346  1.1.1.1.2.2  pgoyette 		p_config "num.query.flags.Z" "Z (zero) flag" "ABSOLUTE"
    347  1.1.1.1.2.2  pgoyette 		p_config "num.query.flags.AD" "AD (auth data) flag" "ABSOLUTE"
    348  1.1.1.1.2.2  pgoyette 		p_config "num.query.flags.CD" "CD (check disabled) flag" "ABSOLUTE"
    349  1.1.1.1.2.2  pgoyette 		p_config "num.query.edns.present" "EDNS OPT present" "ABSOLUTE"
    350  1.1.1.1.2.2  pgoyette 		p_config "num.query.edns.DO" "DO (DNSSEC OK) flag" "ABSOLUTE"
    351  1.1.1.1.2.2  pgoyette 		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."
    352  1.1.1.1.2.2  pgoyette 		;;
    353  1.1.1.1.2.2  pgoyette 	histogram)
    354  1.1.1.1.2.2  pgoyette 		echo "graph_title Unbound DNS histogram of reply time"
    355  1.1.1.1.2.2  pgoyette 		echo "graph_args --base 1000 -l 0"
    356  1.1.1.1.2.2  pgoyette 		echo "graph_vlabel queries / \${graph_period}"
    357  1.1.1.1.2.2  pgoyette 		echo "graph_scale no"
    358  1.1.1.1.2.2  pgoyette 		echo "graph_category DNS"
    359  1.1.1.1.2.2  pgoyette 		echo hcache.label "cache hits"
    360  1.1.1.1.2.2  pgoyette 		echo hcache.min 0
    361  1.1.1.1.2.2  pgoyette 		echo hcache.type ABSOLUTE
    362  1.1.1.1.2.2  pgoyette 		echo hcache.draw AREA
    363  1.1.1.1.2.2  pgoyette 		echo hcache.colour 999999
    364  1.1.1.1.2.2  pgoyette 		echo h64ms.label "0 msec - 66 msec"
    365  1.1.1.1.2.2  pgoyette 		echo h64ms.min 0
    366  1.1.1.1.2.2  pgoyette 		echo h64ms.type ABSOLUTE
    367  1.1.1.1.2.2  pgoyette 		echo h64ms.draw STACK
    368  1.1.1.1.2.2  pgoyette 		echo h64ms.colour 0000FF
    369  1.1.1.1.2.2  pgoyette 		echo h128ms.label "66 msec - 131 msec"
    370  1.1.1.1.2.2  pgoyette 		echo h128ms.min 0
    371  1.1.1.1.2.2  pgoyette 		echo h128ms.type ABSOLUTE
    372  1.1.1.1.2.2  pgoyette 		echo h128ms.colour 1F00DF
    373  1.1.1.1.2.2  pgoyette 		echo h128ms.draw STACK
    374  1.1.1.1.2.2  pgoyette 		echo h256ms.label "131 msec - 262 msec"
    375  1.1.1.1.2.2  pgoyette 		echo h256ms.min 0
    376  1.1.1.1.2.2  pgoyette 		echo h256ms.type ABSOLUTE
    377  1.1.1.1.2.2  pgoyette 		echo h256ms.draw STACK
    378  1.1.1.1.2.2  pgoyette 		echo h256ms.colour 3F00BF
    379  1.1.1.1.2.2  pgoyette 		echo h512ms.label "262 msec - 524 msec"
    380  1.1.1.1.2.2  pgoyette 		echo h512ms.min 0
    381  1.1.1.1.2.2  pgoyette 		echo h512ms.type ABSOLUTE
    382  1.1.1.1.2.2  pgoyette 		echo h512ms.draw STACK
    383  1.1.1.1.2.2  pgoyette 		echo h512ms.colour 5F009F
    384  1.1.1.1.2.2  pgoyette 		echo h1s.label "524 msec - 1 sec"
    385  1.1.1.1.2.2  pgoyette 		echo h1s.min 0
    386  1.1.1.1.2.2  pgoyette 		echo h1s.type ABSOLUTE
    387  1.1.1.1.2.2  pgoyette 		echo h1s.draw STACK
    388  1.1.1.1.2.2  pgoyette 		echo h1s.colour 7F007F
    389  1.1.1.1.2.2  pgoyette 		echo h2s.label "1 sec - 2 sec"
    390  1.1.1.1.2.2  pgoyette 		echo h2s.min 0
    391  1.1.1.1.2.2  pgoyette 		echo h2s.type ABSOLUTE
    392  1.1.1.1.2.2  pgoyette 		echo h2s.draw STACK
    393  1.1.1.1.2.2  pgoyette 		echo h2s.colour 9F005F
    394  1.1.1.1.2.2  pgoyette 		echo h4s.label "2 sec - 4 sec"
    395  1.1.1.1.2.2  pgoyette 		echo h4s.min 0
    396  1.1.1.1.2.2  pgoyette 		echo h4s.type ABSOLUTE
    397  1.1.1.1.2.2  pgoyette 		echo h4s.draw STACK
    398  1.1.1.1.2.2  pgoyette 		echo h4s.colour BF003F
    399  1.1.1.1.2.2  pgoyette 		echo h8s.label "4 sec - 8 sec"
    400  1.1.1.1.2.2  pgoyette 		echo h8s.min 0
    401  1.1.1.1.2.2  pgoyette 		echo h8s.type ABSOLUTE
    402  1.1.1.1.2.2  pgoyette 		echo h8s.draw STACK
    403  1.1.1.1.2.2  pgoyette 		echo h8s.colour DF001F
    404  1.1.1.1.2.2  pgoyette 		echo h16s.label "8 sec - ..."
    405  1.1.1.1.2.2  pgoyette 		echo h16s.min 0
    406  1.1.1.1.2.2  pgoyette 		echo h16s.type ABSOLUTE
    407  1.1.1.1.2.2  pgoyette 		echo h16s.draw STACK
    408  1.1.1.1.2.2  pgoyette 		echo h16s.colour FF0000
    409  1.1.1.1.2.2  pgoyette 		echo "graph_info Histogram of the reply times for queries."
    410  1.1.1.1.2.2  pgoyette 		;;
    411  1.1.1.1.2.2  pgoyette 	esac
    412  1.1.1.1.2.2  pgoyette 
    413  1.1.1.1.2.2  pgoyette 	exit 0
    414  1.1.1.1.2.2  pgoyette fi
    415  1.1.1.1.2.2  pgoyette 
    416  1.1.1.1.2.2  pgoyette # do the stats itself
    417  1.1.1.1.2.2  pgoyette get_state
    418  1.1.1.1.2.2  pgoyette 
    419  1.1.1.1.2.2  pgoyette # get the time elapsed
    420  1.1.1.1.2.2  pgoyette get_value "time.elapsed"
    421  1.1.1.1.2.2  pgoyette if test $value = 0 || test $value = "0.000000"; then
    422  1.1.1.1.2.2  pgoyette 	echo "error: time elapsed 0 or could not retrieve data"
    423  1.1.1.1.2.2  pgoyette 	exit 1
    424  1.1.1.1.2.2  pgoyette fi
    425  1.1.1.1.2.2  pgoyette elapsed="$value"
    426  1.1.1.1.2.2  pgoyette 
    427  1.1.1.1.2.2  pgoyette # print value for $1
    428  1.1.1.1.2.2  pgoyette print_value ( ) {
    429  1.1.1.1.2.2  pgoyette 	mn=`echo $1 | sed $ABBREV | tr . _`
    430  1.1.1.1.2.2  pgoyette 	get_value $1
    431  1.1.1.1.2.2  pgoyette 	echo "$mn.value" $value
    432  1.1.1.1.2.2  pgoyette }
    433  1.1.1.1.2.2  pgoyette 
    434  1.1.1.1.2.2  pgoyette # print value if line already found in $2
    435  1.1.1.1.2.2  pgoyette print_value_line ( ) {
    436  1.1.1.1.2.2  pgoyette 	mn=`echo $1 | sed $ABBREV | tr . _`
    437  1.1.1.1.2.2  pgoyette 	value="`echo $2 | sed -e 's/^.*=//'`"
    438  1.1.1.1.2.2  pgoyette 	echo "$mn.value" $value
    439  1.1.1.1.2.2  pgoyette }
    440  1.1.1.1.2.2  pgoyette 
    441  1.1.1.1.2.2  pgoyette 
    442  1.1.1.1.2.2  pgoyette case $id in
    443  1.1.1.1.2.2  pgoyette hits)
    444  1.1.1.1.2.2  pgoyette 	for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
    445  1.1.1.1.2.2  pgoyette 		sed -e 's/=.*//'` total.num.queries \
    446  1.1.1.1.2.2  pgoyette 		total.num.cachehits total.num.prefetch num.query.tcp \
    447  1.1.1.1.2.2  pgoyette 		num.query.tcpout num.query.ipv6 unwanted.queries \
    448  1.1.1.1.2.2  pgoyette 		unwanted.replies; do
    449  1.1.1.1.2.2  pgoyette 		if grep "^"$x"=" $state >/dev/null 2>&1; then
    450  1.1.1.1.2.2  pgoyette 			print_value $x
    451  1.1.1.1.2.2  pgoyette 		fi
    452  1.1.1.1.2.2  pgoyette 	done
    453  1.1.1.1.2.2  pgoyette 	;;
    454  1.1.1.1.2.2  pgoyette queue)
    455  1.1.1.1.2.2  pgoyette 	for x in total.requestlist.avg total.requestlist.max \
    456  1.1.1.1.2.2  pgoyette 		total.requestlist.overwritten total.requestlist.exceeded; do
    457  1.1.1.1.2.2  pgoyette 		print_value $x
    458  1.1.1.1.2.2  pgoyette 	done
    459  1.1.1.1.2.2  pgoyette 	;;
    460  1.1.1.1.2.2  pgoyette memory)
    461  1.1.1.1.2.2  pgoyette 	mn=`echo mem.total.sbrk | sed $ABBREV | tr . _`
    462  1.1.1.1.2.2  pgoyette 	get_value 'mem.total.sbrk'
    463  1.1.1.1.2.2  pgoyette 	if test $value -eq 0; then
    464  1.1.1.1.2.2  pgoyette 		chk=`echo $ctrl | sed -e 's/-control$/-checkconf/'`
    465  1.1.1.1.2.2  pgoyette 		pidf=`$chk -o pidfile $conf 2>&1`
    466  1.1.1.1.2.2  pgoyette 		pid=`cat $pidf 2>&1`
    467  1.1.1.1.2.2  pgoyette 		value=`ps -p "$pid" -o rss= 2>&1`
    468  1.1.1.1.2.2  pgoyette 		if test "`expr $value + 1 - 1 2>&1`" -eq "$value" 2>&1; then
    469  1.1.1.1.2.2  pgoyette 			value=`expr $value \* 1024` 
    470  1.1.1.1.2.2  pgoyette 		else
    471  1.1.1.1.2.2  pgoyette 			value=0
    472  1.1.1.1.2.2  pgoyette 		fi
    473  1.1.1.1.2.2  pgoyette 	fi
    474  1.1.1.1.2.2  pgoyette 	echo "$mn.value" $value
    475  1.1.1.1.2.2  pgoyette 	for x in mem.cache.rrset mem.cache.message mem.mod.iterator \
    476  1.1.1.1.2.2  pgoyette 		mem.mod.validator msg.cache.count rrset.cache.count \
    477  1.1.1.1.2.2  pgoyette 		infra.cache.count key.cache.count; do
    478  1.1.1.1.2.2  pgoyette 		print_value $x
    479  1.1.1.1.2.2  pgoyette 	done
    480  1.1.1.1.2.2  pgoyette 	;;
    481  1.1.1.1.2.2  pgoyette by_type)
    482  1.1.1.1.2.2  pgoyette 	for x in `grep "^num.query.type" $state`; do
    483  1.1.1.1.2.2  pgoyette 		nm=`echo $x | sed -e 's/=.*$//'`
    484  1.1.1.1.2.2  pgoyette 		print_value_line $nm $x
    485  1.1.1.1.2.2  pgoyette 	done
    486  1.1.1.1.2.2  pgoyette 	;;
    487  1.1.1.1.2.2  pgoyette by_class)
    488  1.1.1.1.2.2  pgoyette 	for x in `grep "^num.query.class" $state`; do
    489  1.1.1.1.2.2  pgoyette 		nm=`echo $x | sed -e 's/=.*$//'`
    490  1.1.1.1.2.2  pgoyette 		print_value_line $nm $x
    491  1.1.1.1.2.2  pgoyette 	done
    492  1.1.1.1.2.2  pgoyette 	;;
    493  1.1.1.1.2.2  pgoyette by_opcode)
    494  1.1.1.1.2.2  pgoyette 	for x in `grep "^num.query.opcode" $state`; do
    495  1.1.1.1.2.2  pgoyette 		nm=`echo $x | sed -e 's/=.*$//'`
    496  1.1.1.1.2.2  pgoyette 		print_value_line $nm $x
    497  1.1.1.1.2.2  pgoyette 	done
    498  1.1.1.1.2.2  pgoyette 	;;
    499  1.1.1.1.2.2  pgoyette by_rcode)
    500  1.1.1.1.2.2  pgoyette 	for x in `grep "^num.answer.rcode" $state`; do
    501  1.1.1.1.2.2  pgoyette 		nm=`echo $x | sed -e 's/=.*$//'`
    502  1.1.1.1.2.2  pgoyette 		print_value_line $nm $x
    503  1.1.1.1.2.2  pgoyette 	done
    504  1.1.1.1.2.2  pgoyette 	print_value "num.answer.secure"
    505  1.1.1.1.2.2  pgoyette 	print_value "num.answer.bogus"
    506  1.1.1.1.2.2  pgoyette 	print_value "num.rrset.bogus"
    507  1.1.1.1.2.2  pgoyette 	;;
    508  1.1.1.1.2.2  pgoyette by_flags)
    509  1.1.1.1.2.2  pgoyette 	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
    510  1.1.1.1.2.2  pgoyette 		print_value $x
    511  1.1.1.1.2.2  pgoyette 	done
    512  1.1.1.1.2.2  pgoyette 	;;
    513  1.1.1.1.2.2  pgoyette histogram)
    514  1.1.1.1.2.2  pgoyette 	get_value total.num.cachehits
    515  1.1.1.1.2.2  pgoyette 	echo hcache.value $value
    516  1.1.1.1.2.2  pgoyette 	r=0
    517  1.1.1.1.2.2  pgoyette 	for x in histogram.000000.000000.to.000000.000001 \
    518  1.1.1.1.2.2  pgoyette 		histogram.000000.000001.to.000000.000002 \
    519  1.1.1.1.2.2  pgoyette 		histogram.000000.000002.to.000000.000004 \
    520  1.1.1.1.2.2  pgoyette 		histogram.000000.000004.to.000000.000008 \
    521  1.1.1.1.2.2  pgoyette 		histogram.000000.000008.to.000000.000016 \
    522  1.1.1.1.2.2  pgoyette 		histogram.000000.000016.to.000000.000032 \
    523  1.1.1.1.2.2  pgoyette 		histogram.000000.000032.to.000000.000064 \
    524  1.1.1.1.2.2  pgoyette 		histogram.000000.000064.to.000000.000128 \
    525  1.1.1.1.2.2  pgoyette 		histogram.000000.000128.to.000000.000256 \
    526  1.1.1.1.2.2  pgoyette 		histogram.000000.000256.to.000000.000512 \
    527  1.1.1.1.2.2  pgoyette 		histogram.000000.000512.to.000000.001024 \
    528  1.1.1.1.2.2  pgoyette 		histogram.000000.001024.to.000000.002048 \
    529  1.1.1.1.2.2  pgoyette 		histogram.000000.002048.to.000000.004096 \
    530  1.1.1.1.2.2  pgoyette 		histogram.000000.004096.to.000000.008192 \
    531  1.1.1.1.2.2  pgoyette 		histogram.000000.008192.to.000000.016384 \
    532  1.1.1.1.2.2  pgoyette 		histogram.000000.016384.to.000000.032768 \
    533  1.1.1.1.2.2  pgoyette 		histogram.000000.032768.to.000000.065536; do
    534  1.1.1.1.2.2  pgoyette 		get_value $x
    535  1.1.1.1.2.2  pgoyette 		r=`expr $r + $value`
    536  1.1.1.1.2.2  pgoyette 	done
    537  1.1.1.1.2.2  pgoyette 	echo h64ms.value $r
    538  1.1.1.1.2.2  pgoyette 	get_value histogram.000000.065536.to.000000.131072
    539  1.1.1.1.2.2  pgoyette 	echo h128ms.value $value
    540  1.1.1.1.2.2  pgoyette 	get_value histogram.000000.131072.to.000000.262144
    541  1.1.1.1.2.2  pgoyette 	echo h256ms.value $value
    542  1.1.1.1.2.2  pgoyette 	get_value histogram.000000.262144.to.000000.524288
    543  1.1.1.1.2.2  pgoyette 	echo h512ms.value $value
    544  1.1.1.1.2.2  pgoyette 	get_value histogram.000000.524288.to.000001.000000
    545  1.1.1.1.2.2  pgoyette 	echo h1s.value $value
    546  1.1.1.1.2.2  pgoyette 	get_value histogram.000001.000000.to.000002.000000
    547  1.1.1.1.2.2  pgoyette 	echo h2s.value $value
    548  1.1.1.1.2.2  pgoyette 	get_value histogram.000002.000000.to.000004.000000
    549  1.1.1.1.2.2  pgoyette 	echo h4s.value $value
    550  1.1.1.1.2.2  pgoyette 	get_value histogram.000004.000000.to.000008.000000
    551  1.1.1.1.2.2  pgoyette 	echo h8s.value $value
    552  1.1.1.1.2.2  pgoyette 	r=0
    553  1.1.1.1.2.2  pgoyette 	for x in histogram.000008.000000.to.000016.000000 \
    554  1.1.1.1.2.2  pgoyette 		histogram.000016.000000.to.000032.000000 \
    555  1.1.1.1.2.2  pgoyette 		histogram.000032.000000.to.000064.000000 \
    556  1.1.1.1.2.2  pgoyette 		histogram.000064.000000.to.000128.000000 \
    557  1.1.1.1.2.2  pgoyette 		histogram.000128.000000.to.000256.000000 \
    558  1.1.1.1.2.2  pgoyette 		histogram.000256.000000.to.000512.000000 \
    559  1.1.1.1.2.2  pgoyette 		histogram.000512.000000.to.001024.000000 \
    560  1.1.1.1.2.2  pgoyette 		histogram.001024.000000.to.002048.000000 \
    561  1.1.1.1.2.2  pgoyette 		histogram.002048.000000.to.004096.000000 \
    562  1.1.1.1.2.2  pgoyette 		histogram.004096.000000.to.008192.000000 \
    563  1.1.1.1.2.2  pgoyette 		histogram.008192.000000.to.016384.000000 \
    564  1.1.1.1.2.2  pgoyette 		histogram.016384.000000.to.032768.000000 \
    565  1.1.1.1.2.2  pgoyette 		histogram.032768.000000.to.065536.000000 \
    566  1.1.1.1.2.2  pgoyette 		histogram.065536.000000.to.131072.000000 \
    567  1.1.1.1.2.2  pgoyette 		histogram.131072.000000.to.262144.000000 \
    568  1.1.1.1.2.2  pgoyette 		histogram.262144.000000.to.524288.000000; do
    569  1.1.1.1.2.2  pgoyette 		get_value $x
    570  1.1.1.1.2.2  pgoyette 		r=`expr $r + $value`
    571  1.1.1.1.2.2  pgoyette 	done
    572  1.1.1.1.2.2  pgoyette 	echo h16s.value $r
    573  1.1.1.1.2.2  pgoyette 	;;
    574  1.1.1.1.2.2  pgoyette esac
    575