#!/usr/bin/env perl #Copyright (c) 2017, Zane C. Bowers-Hadley #All rights reserved. # #Redistribution and use in source and binary forms, with or without modification, #are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # #THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED #WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. #IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, #INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, #BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, #DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF #LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR #OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF #THE POSSIBILITY OF SUCH DAMAGE. =for comment Add this to snmpd.conf as below and restart it. extend bind /etc/snmp/bind You may also need to create the config file, which defaults to the same path as the script, but with .config appended. So if the script is located at /etc/snmp/bind, the config file will be /etc/snmp/bind.config. Alternatively you can also specific a config via -c. Anything starting with a # is comment. The format for variables is $variable=$value. Empty lines are ignored. Spaces and tabes at either the start or end of a line are ignored. The variables are as below. rndc = The path to rndc. Default: /usr/bin/env rndc call_rndc = A 0/1 boolean on weather to call rndc stats. Suggest to set to 0 if using netdata. Default: 1 stats_file = The path to the named stats file. Default: /var/run/named/stats agent = A 0/1 boolean for if this is being used as a LibreNMS agent or not. Default: 0 zero_stats = A 0/1 boolean for if the stats file should be zeroed first. Default: 0 (1 if guessed) If you want to guess at the configuration, call it with -g and it will print out what it thinks it should be. =cut ## ## You should not need to touch anything below here. ## my $call_rndc=1; my $rndc='/usr/bin/env rndc'; my $stats_file='/var/run/named/stats'; my $zero_stats=0; my $agent=0; my $missing=0; use strict; use warnings; use File::ReadBackwards; use Getopt::Std; $Getopt::Std::STANDARD_HELP_VERSION = 1; sub main::VERSION_MESSAGE { print "BIND named stats extend 0.0.0\n"; }; sub main::HELP_MESSAGE { print "\n". "-c The config file to use.\n". "-m print any unknowns and exit\n". "-g Guess at the config and print it to STDOUT.\n"; } #gets the options my %opts=(); getopts('gmc:', \%opts); # guess if asked if ( defined( $opts{g} ) ){ #get what path to use for rndc $rndc=`which rndc`; chomp($rndc); if ( $? != 0 ){ warn("'which rndc' failed with a exit code of $?"); exit 1; }else{ $rndc="# This is the path to rndc.\n". 'rndc='.$rndc."\n"; } #make a basic guess at the stats file if ( -f $stats_file ){ # a more sane location $stats_file="# This is the the path to the named stats file.\n". 'stats_file='.$stats_file."\n"; }elsif( -f '/etc/bind/named.stats' ){ # this is if the person using the old suggested config in the LibreNMS docs $stats_file="# This is the the path to the named stats file.\n". "stats_file=/etc/bind/named.stats\n"; }else{ #we find it $stats_file="# This is the the path to the named stats file.\n". "# Please make sure this has been set to the value of statistics-file in named.conf.\n". "stats_file=?\n"; } if ( $0 =~ /agent/ ){ $agent='agent=1'; }else{ $agent='agent=0'; } print "# The default config file is... ".$0.".config\n". $rndc. $stats_file. "# This is a 0/1 boolean for if rndc should be called.\n". "# If you are using netdata, you most likely want to set this to 0.\n". "call_rndc=1\n". "# This is a 0/1 boolean for this is being used as a LibreNMS agent.\n". $agent."\n". "# This is a 0/1 boolean for if the stats file should be zeroed before calling rndc stats.\n". "zero_stats=1\n"; exit 0; } #get which config file to use my $config=$0.'.config'; if ( defined( $opts{c} ) ){ $config=$opts{c}; } #reads the config file my $config_file=''; if ( -f $config ){ open(my $readfh, "<", $config) or die "Can't open '".$config."'"; read($readfh , $config_file , 1000000); close($readfh); #parse the config file and remove comments and empty lines my @configA=split(/\n/, $config_file); @configA=grep(!/^$/, @configA); @configA=grep(!/^\#/, @configA); @configA=grep(!/^[\s\t]*$/, @configA); my $configA_int=0; while ( defined( $configA[$configA_int] ) ){ my $line=$configA[$configA_int]; $line=~s/^[\t\s]+//; $line=~s/[\t\s]+$//; my ( $var, $val )=split(/=/, $line, 2); if ( $var eq 'call_rndc' ){ $call_rndc=$val; } if ( $var eq 'rndc' ){ $rndc=$val; } if ( $var eq 'stats_file' ){ $stats_file=$val; } if ( $var eq 'agent' ){ $agent=$val; } if ( $var eq 'zero_stats' ){ $zero_stats=$val; } $configA_int++; } } #zero the stats if needed if ( $zero_stats ){ system('echo > '.$stats_file); if ( $? != 0 ){ die ("'echo > $stats_file' failed with a system return value of $?"); } } # call rndc if needed and die if it failes if ( $call_rndc ){ system($rndc.' stats'); if ( $? != 0 ){ die ("'$rndc stats' failed with a system return value of $?"); } } my $bw=File::ReadBackwards->new( $stats_file ) or die( "con't read '$stats_file': $!" ); #read backwards till we find the start of the last stats entry my $read=1; my @data; until ( ($bw->eof) || ( ! $read ) ){ my $new_line=$bw->readline; $data[$#data++]=$new_line; if ($new_line =~ /^\+\+\+\ Statistics\ Dump\ \+\+\+/){ $read=0; } } my %incoming=( 'A'=>0, 'AAAA'=>0, 'AFSDB'=>0, 'APL'=>0, 'CAA'=>0, 'CDNSKEY'=>0, 'CDS'=>0, 'CERT'=>0, 'CNAME'=>0, 'DHCID'=>0, 'DLV'=>0, 'DNSKEY'=>0, 'DS'=>0, 'IPSECKEY'=>0, 'KEY'=>0, 'KX'=>0, 'LOC'=>0, 'MX'=>0, 'NAPTR'=>0, 'NS'=>0, 'NSEC'=>0, 'NSEC3'=>0, 'NSEC3PARAM'=>0, 'PTR'=>0, 'RRSIG'=>0, 'RP'=>0, 'SIG'=>0, 'SOA'=>0, 'SRV'=>0, 'SSHFP'=>0, 'TA'=>0, 'TKEY'=>0, 'TLSA'=>0, 'TSIG'=>0, 'TXT'=>0, 'URI'=>0, 'DNAME'=>0, 'ANY'=>0, 'AXFR'=>0, 'IXFR'=>0, 'OPT'=>0, 'SPF'=>0, ); my %outgoing=( 'A'=>0, 'AAAA'=>0, 'AFSDB'=>0, 'APL'=>0, 'CAA'=>0, 'CDNSKEY'=>0, 'CDS'=>0, 'CERT'=>0, 'CNAME'=>0, 'DHCID'=>0, 'DLV'=>0, 'DNSKEY'=>0, 'DS'=>0, 'IPSECKEY'=>0, 'KEY'=>0, 'KX'=>0, 'LOC'=>0, 'MX'=>0, 'NAPTR'=>0, 'NS'=>0, 'NSEC'=>0, 'NSEC3'=>0, 'NSEC3PARAM'=>0, 'PTR'=>0, 'RRSIG'=>0, 'RP'=>0, 'SIG'=>0, 'SOA'=>0, 'SRV'=>0, 'SSHFP'=>0, 'TA'=>0, 'TKEY'=>0, 'TLSA'=>0, 'TSIG'=>0, 'TXT'=>0, 'URI'=>0, 'DNAME'=>0, 'ANY'=>0, 'AXFR'=>0, 'IXFR'=>0, 'OPT'=>0, 'SPF'=>0, ); my %server=( 'IPv4 requests received'=>0, #i4rr 'IPv6 requests received'=>0, #i6rr 'requests with EDNS(0) received'=>0, #rwer 'TCP requests received'=>0, #trr 'auth queries rejected'=>0, #aqr 'recursive queries rejected'=>0, #rqr 'responses sent'=>0, #rs 'truncated responses sent'=>0, #trs 'responses with EDNS(0) sent'=>0, #rwes 'queries resulted in successful answer'=>0, #qrisa 'queries resulted in authoritative answer'=>0, #qriaa 'queries resulted in non authoritative answer'=>0, #qrinaa 'queries resulted in nxrrset'=>0, #qrin 'queries resulted in SERVFAIL'=>0, #qris 'queries resulted in NXDOMAIN'=>0, #qrind 'queries caused recursion'=>0, #qcr 'duplicate queries received'=>0, #dqr 'other query failures'=>0, #oqf 'UDP queries received'=>0, #uqr 'TCP queries received'=>0, #tqr 'Other EDNS option received'=>0, #oeor 'queries dropped'=>0, #qd ); my %resolver=( 'IPv4 queries sent'=>0, #i4qs 'IPv6 queries sent'=>0, #i6qs 'IPv4 responses received'=>0, #i4rr 'IPv6 responses received'=>0, #i6rr 'NXDOMAIN received'=>0, #nr 'SERVFAIL received'=>0, #sr 'FORMERR received'=>0, #fr 'EDNS(0) query failures'=>0, #eqf 'truncated responses received'=>0, #trr 'lame delegations received'=>0, #ldr 'query retries'=>0, #qr 'query timeouts'=>0, #qt 'IPv4 NS address fetches'=>0, #i4naf 'IPv6 NS address fetches'=>0, #i6naf 'IPv4 NS address fetch failed'=>0, #i4naff 'IPv6 NS address fetch failed'=>0, #i6naff 'queries with RTT < 10ms'=>0, #rttl10 'queries with RTT 10-100ms'=>0, #rtt10t100 'queries with RTT 100-500ms'=>0, #rtt100t500 'queries with RTT 500-800ms'=>0, #rtt500t800 'queries with RTT 800-1600ms'=>0, #rtt800t1600 'queries with RTT > 1600ms'=>0, #rttg1600 'bucket size'=>0, #bs 'REFUSED received'=>0 #rr ); my %cache=( 'cache hits'=>0, #ch 'cache misses'=>0, #cm 'cache hits (from query)'=>0, #chfq 'cache misses (from query)'=>0, #cmfq 'cache records deleted due to memory exhaustion'=>0, #crddtme 'cache records deleted due to TTL expiration'=>0, #crddtte 'cache database nodes'=>0, #cdn 'cache database hash buckets'=>0, #cdhb 'cache tree memory total'=>0, #ctmt 'cache tree memory in use'=>0, #ctmiu 'cache tree highest memory in use'=>0, #cthmiu 'cache heap memory total'=>0, #chmt 'cache heap memory in use'=>0, #chmiu 'cache heap highest memory in use'=>0,#chhmiu ); my %RRsets=( 'A'=>0, 'AAAA'=>0, 'AFSDB'=>0, 'APL'=>0, 'CAA'=>0, 'CDNSKEY'=>0, 'CDS'=>0, 'CERT'=>0, 'CNAME'=>0, 'DHCID'=>0, 'DLV'=>0, 'DNSKEY'=>0, 'DS'=>0, 'IPSECKEY'=>0, 'KEY'=>0, 'KX'=>0, 'LOC'=>0, 'MX'=>0, 'NAPTR'=>0, 'NS'=>0, 'NSEC'=>0, 'NSEC3'=>0, 'NSEC3PARAM'=>0, 'PTR'=>0, 'RRSIG'=>0, 'RP'=>0, 'SIG'=>0, 'SOA'=>0, 'SRV'=>0, 'SSHFP'=>0, 'TA'=>0, 'TKEY'=>0, 'TLSA'=>0, 'TSIG'=>0, 'TXT'=>0, 'URI'=>0, 'DNAME'=>0, 'NXDOMAIN'=>0, 'ANY'=>0, 'AXFR'=>0, 'IXFR'=>0, 'OPT'=>0, 'SPF'=>0, '!A'=>0, '!AAAA'=>0, '!AFSDB'=>0, '!APL'=>0, '!CAA'=>0, '!CDNSKEY'=>0, '!CDS'=>0, '!CERT'=>0, '!CNAME'=>0, '!DHCID'=>0, '!DLV'=>0, '!DNSKEY'=>0, '!DS'=>0, '!IPSECKEY'=>0, '!KEY'=>0, '!KX'=>0, '!LOC'=>0, '!MX'=>0, '!NAPTR'=>0, '!NS'=>0, '!NSEC'=>0, '!NSEC3'=>0, '!NSEC3PARAM'=>0, '!PTR'=>0, '!RRSIG'=>0, '!RP'=>0, '!SIG'=>0, '!SOA'=>0, '!SRV'=>0, '!SSHFP'=>0, '!TA'=>0, '!TKEY'=>0, '!TLSA'=>0, '!TSIG'=>0, '!TXT'=>0, '!URI'=>0, '!DNAME'=>0, '!NXDOMAIN'=>0, '!ANY'=>0, '!AXFR'=>0, '!IXFR'=>0, '!OPT'=>0, '!SPF'=>0, ); my %ADB=( 'Address hash table size'=>0, #ahts 'Addresses in hash table'=>0, #aiht 'Name hash table size'=>0, #nhts 'Names in hash table'=>0, #niht ); my %sockets=( 'UDP/IPv4 sockets opened'=>0, #ui4so 'UDP/IPv6 sockets opened'=>0, #ui6so 'TCP/IPv4 sockets opened'=>0, #ti4so 'TCP/IPv6 sockets opened'=>0, #ti6so 'Raw sockets opened'=>0, #rso 'UDP/IPv4 sockets closed'=>0, #ui4sc 'UDP/IPv6 sockets closed'=>0, #ui6sc 'TCP/IPv4 sockets closed'=>0, #ti4sc 'TCP/IPv6 sockets closed'=>0, #ti6sc 'UDP/IPv4 socket bind failures'=>0, #ui4sbf 'TCP/IPv4 socket bind failures'=>0, #ti4sbf 'UDP/IPv6 socket bind failures'=>0, #ui6sbf 'TCP/IPv6 socket bind failures'=>0, #ti6sbf 'UDP/IPv4 socket connect failures'=>0, #ui4scf 'TCP/IPv4 socket connect failures'=>0, #ti4scf 'UDP/IPv6 socket connect failures'=>0, #ui6scf 'TCP/IPv6 socket connect failures'=>0, #ti6scf 'UDP/IPv4 connections established'=>0, #ui4ce 'TCP/IPv4 connections established'=>0, #ti4ce 'UDP/IPv6 connections established'=>0, #ui6ce 'TCP/IPv6 connections established'=>0, #ti6ce 'TCP/IPv4 connections accepted'=>0, #ti4ca 'TCP/IPv6 connections accepted'=>0, #ti6ca 'UDP/IPv4 send errors'=>0, #ui4se 'TCP/IPv4 send errors'=>0, #ti4se 'UDP/IPv6 send errors'=>0, #ui6se 'TCP/IPv6 send errors'=>0, #ti6se 'UDP/IPv4 recv errors'=>0, #ui4re 'TCP/IPv4 recv errors'=>0, #ti4re 'UDP/IPv6 recv errors'=>0, #ui6re 'TCP/IPv6 recv errors'=>0, #ti6re 'UDP/IPv4 sockets active'=>0, #ui4sa 'UDP/IPv6 sockets active'=>0, #ui6sa 'TCP/IPv4 sockets active'=>0, #ti4sa 'TCP/IPv6 sockets active'=>0, #ti6sa 'Raw sockets active'=>0, #rsa ); my $int=$#data-1; my $section=''; while ( defined( $data[$int] ) ){ my $line=$data[$int]; my $done=0; if ( $line =~ /^\+\+\ Incoming\ Queries\ \+\+/ ){ $section='incoming'; $done=1; }elsif( $line =~ /\+\+\ Outgoing\ Queries\ \+\+/ ){ $section='outgoing'; $done=1; }elsif( $line =~ /^\+\+\ Name\ Server\ Statistics\ \+\+/ ){ $section='server'; $done=1; }elsif( $line =~ /^\+\+\ Resolver\ Statistics\ \+\+/ ){ $section='resolver'; $done=1; }elsif( $line =~ /^\+\+\ Cache\ Statistics\ \+\+/ ){ $section='cache'; $done=1; }elsif( $line =~ /^\+\+\ Cache\ DB\ RRsets\ \+\+/ ){ $section='RRsets'; $done=1; }elsif( $line =~ /^\+\+\ ADB\ stats\ \+\+/ ){ $section='ADB'; $done=1; }elsif( $line =~ /^\+\+\ Socket\ I\/O\ Statistics\ \+\+/ ){ $section='sockets'; $done=1; }elsif( $line =~ /^\[/ ){ $done=1; }elsif( $line !~ /^[\s\t]/){ $section=''; } if ( ( $section ne '' ) && ( ! $done ) ) { $line=~s/^[\t\s]+//; chomp($line); my ( $count, $type )=split(/ /, $line, 2); if ( defined( $opts{m} ) ){ eval( 'if (! defined($'.$section.'{$type} ) ){ print $section.",".$type.",".$count."\n";}' ); } my $to_eval='if( defined($'.$section.'{$type}) ){$'.$section.'{$type}=$'.$section.'{$type}+$count;}'; eval( $to_eval ); } $int--; } #exit now if we are just checking for missing items if ( defined( $opts{m} ) ){ exit 0; } if ( $agent ){ print "<<>>\n"; } print $incoming{'A'}.','. $incoming{'AAAA'}.','. $incoming{'AFSDB'}.','. $incoming{'APL'}.','. $incoming{'CAA'}.','. $incoming{'CDNSKEY'}.','. $incoming{'CDS'}.','. $incoming{'CERT'}.','. $incoming{'CNAME'}.','. $incoming{'DHCID'}.','. $incoming{'DLV'}.','. $incoming{'DNSKEY'}.','. $incoming{'DS'}.','. $incoming{'IPSECKEY'}.','. $incoming{'KEY'}.','. $incoming{'KX'}.','. $incoming{'LOC'}.','. $incoming{'MX'}.','. $incoming{'NAPTR'}.','. $incoming{'NS'}.','. $incoming{'NSEC'}.','. $incoming{'NSEC3'}.','. $incoming{'NSEC3PARAM'}.','. $incoming{'PTR'}.','. $incoming{'RRSIG'}.','. $incoming{'RP'}.','. $incoming{'SIG'}.','. $incoming{'SOA'}.','. $incoming{'SRV'}.','. $incoming{'SSHFP'}.','. $incoming{'TA'}.','. $incoming{'TKEY'}.','. $incoming{'TLSA'}.','. $incoming{'TSIG'}.','. $incoming{'TXT'}.','. $incoming{'URI'}.','. $incoming{'DNAME'}.','. $incoming{'ANY'}.','. $incoming{'AXFR'}.','. $incoming{'IXFR'}.','. $incoming{'OPT'}.','. $incoming{'SPF'}."\n"; print $outgoing{'A'}.','. $outgoing{'AAAA'}.','. $outgoing{'AFSDB'}.','. $outgoing{'APL'}.','. $outgoing{'CAA'}.','. $outgoing{'CDNSKEY'}.','. $outgoing{'CDS'}.','. $outgoing{'CERT'}.','. $outgoing{'CNAME'}.','. $outgoing{'DHCID'}.','. $outgoing{'DLV'}.','. $outgoing{'DNSKEY'}.','. $outgoing{'DS'}.','. $outgoing{'IPSECKEY'}.','. $outgoing{'KEY'}.','. $outgoing{'KX'}.','. $outgoing{'LOC'}.','. $outgoing{'MX'}.','. $outgoing{'NAPTR'}.','. $outgoing{'NS'}.','. $outgoing{'NSEC'}.','. $outgoing{'NSEC3'}.','. $outgoing{'NSEC3PARAM'}.','. $outgoing{'PTR'}.','. $outgoing{'RRSIG'}.','. $outgoing{'RP'}.','. $outgoing{'SIG'}.','. $outgoing{'SOA'}.','. $outgoing{'SRV'}.','. $outgoing{'SSHFP'}.','. $outgoing{'TA'}.','. $outgoing{'TKEY'}.','. $outgoing{'TLSA'}.','. $outgoing{'TSIG'}.','. $outgoing{'TXT'}.','. $outgoing{'URI'}.','. $outgoing{'DNAME'}.','. $outgoing{'ANY'}.','. $outgoing{'AXFR'}.','. $outgoing{'IXFR'}.','. $outgoing{'OPT'}.','. $outgoing{'SPF'}."\n"; print $server{'IPv4 requests received'}.','. $server{'IPv6 requests received'}.','. $server{'requests with EDNS(0) received'}.','. $server{'TCP requests received'}.','. $server{'auth queries rejected'}.','. $server{'recursive queries rejected'}.','. $server{'responses sent'}.','. $server{'truncated responses sent'}.','. $server{'responses with EDNS(0) sent'}.','. $server{'queries resulted in successful answer'}.','. $server{'queries resulted in authoritative answer'}.','. $server{'queries resulted in non authoritative answer'}.','. $server{'queries resulted in nxrrset'}.','. $server{'queries resulted in SERVFAIL'}.','. $server{'queries resulted in NXDOMAIN'}.','. $server{'queries caused recursion'}.','. $server{'duplicate queries received'}.','. $server{'other query failures'}.','. $server{'UDP queries received'}.','. $server{'TCP queries received'}.','. $server{'Other EDNS option received'}.','. $server{'queries dropped'}."\n"; print $resolver{'IPv4 queries sent'}.','. $resolver{'IPv6 queries sent'}.','. $resolver{'IPv4 responses received'}.','. $resolver{'IPv6 responses received'}.','. $resolver{'NXDOMAIN received'}.','. $resolver{'SERVFAIL received'}.','. $resolver{'FORMERR received'}.','. $resolver{'EDNS(0) query failures'}.','. $resolver{'truncated responses received'}.','. $resolver{'lame delegations received'}.','. $resolver{'query retries'}.','. $resolver{'query timeouts'}.','. $resolver{'IPv4 NS address fetches'}.','. $resolver{'IPv6 NS address fetches'}.','. $resolver{'IPv4 NS address fetch failed'}.','. $resolver{'IPv6 NS address fetch failed'}.','. $resolver{'queries with RTT < 10ms'}.','. $resolver{'queries with RTT 10-100ms'}.','. $resolver{'queries with RTT 100-500ms'}.','. $resolver{'queries with RTT 500-800ms'}.','. $resolver{'queries with RTT 800-1600ms'}.','. $resolver{'queries with RTT > 1600ms'}.','. $resolver{'bucket size'}.','. $resolver{'REFUSED received'}."\n"; print $cache{'cache hits'}.','. $cache{'cache misses'}.','. $cache{'cache hits (from query)'}.','. $cache{'cache misses (from query)'}.','. $cache{'cache records deleted due to memory exhaustion'}.','. $cache{'cache records deleted due to TTL expiration'}.','. $cache{'cache database nodes'}.','. $cache{'cache database hash buckets'}.','. $cache{'cache tree memory total'}.','. $cache{'cache tree memory in use'}.','. $cache{'cache tree highest memory in use'}.','. $cache{'cache heap memory total'}.','. $cache{'cache heap memory in use'}.','. $cache{'cache heap highest memory in use'}."\n"; print $RRsets{'A'}.','. $RRsets{'AAAA'}.','. $RRsets{'AFSDB'}.','. $RRsets{'APL'}.','. $RRsets{'CAA'}.','. $RRsets{'CDNSKEY'}.','. $RRsets{'CDS'}.','. $RRsets{'CERT'}.','. $RRsets{'CNAME'}.','. $RRsets{'DHCID'}.','. $RRsets{'DLV'}.','. $RRsets{'DNSKEY'}.','. $RRsets{'DS'}.','. $RRsets{'IPSECKEY'}.','. $RRsets{'KEY'}.','. $RRsets{'KX'}.','. $RRsets{'LOC'}.','. $RRsets{'MX'}.','. $RRsets{'NAPTR'}.','. $RRsets{'NS'}.','. $RRsets{'NSEC'}.','. $RRsets{'NSEC3'}.','. $RRsets{'NSEC3PARAM'}.','. $RRsets{'PTR'}.','. $RRsets{'RRSIG'}.','. $RRsets{'RP'}.','. $RRsets{'SIG'}.','. $RRsets{'SOA'}.','. $RRsets{'SRV'}.','. $RRsets{'SSHFP'}.','. $RRsets{'TA'}.','. $RRsets{'TKEY'}.','. $RRsets{'TLSA'}.','. $RRsets{'TSIG'}.','. $RRsets{'TXT'}.','. $RRsets{'URI'}.','. $RRsets{'DNAME'}.','. $RRsets{'NXDOMAIN'}.','. $RRsets{'ANY'}.','. $RRsets{'AXFR'}.','. $RRsets{'IXFR'}.','. $RRsets{'OPT'}.','. $RRsets{'SPF'}.','. $RRsets{'!A'}.','. $RRsets{'!AAAA'}.','. $RRsets{'!AFSDB'}.','. $RRsets{'!APL'}.','. $RRsets{'!CAA'}.','. $RRsets{'!CDNSKEY'}.','. $RRsets{'!CDS'}.','. $RRsets{'!CERT'}.','. $RRsets{'!CNAME'}.','. $RRsets{'!DHCID'}.','. $RRsets{'!DLV'}.','. $RRsets{'!DNSKEY'}.','. $RRsets{'!DS'}.','. $RRsets{'!IPSECKEY'}.','. $RRsets{'!KEY'}.','. $RRsets{'!KX'}.','. $RRsets{'!LOC'}.','. $RRsets{'!MX'}.','. $RRsets{'!NAPTR'}.','. $RRsets{'!NS'}.','. $RRsets{'!NSEC'}.','. $RRsets{'!NSEC3'}.','. $RRsets{'!NSEC3PARAM'}.','. $RRsets{'!PTR'}.','. $RRsets{'!RRSIG'}.','. $RRsets{'!RP'}.','. $RRsets{'!SIG'}.','. $RRsets{'!SOA'}.','. $RRsets{'!SRV'}.','. $RRsets{'!SSHFP'}.','. $RRsets{'!TA'}.','. $RRsets{'!TKEY'}.','. $RRsets{'!TLSA'}.','. $RRsets{'!TSIG'}.','. $RRsets{'!TXT'}.','. $RRsets{'!URI'}.','. $RRsets{'!DNAME'}.','. $RRsets{'!NXDOMAIN'}.','. $RRsets{'!ANY'}.','. $RRsets{'!AXFR'}.','. $RRsets{'!IXFR'}.','. $RRsets{'!OPT'}.','. $RRsets{'!SPF'}."\n"; print $ADB{'Address hash table size'}.','. $ADB{'Addresses in hash table'}.','. $ADB{'Name hash table size'}.','. $ADB{'Names in hash table'}."\n"; print $sockets{'UDP/IPv4 sockets opened'}.','. $sockets{'UDP/IPv6 sockets opened'}.','. $sockets{'TCP/IPv4 sockets opened'}.','. $sockets{'TCP/IPv6 sockets opened'}.','. $sockets{'Raw sockets opened'}.','. $sockets{'UDP/IPv4 sockets closed'}.','. $sockets{'UDP/IPv6 sockets closed'}.','. $sockets{'TCP/IPv4 sockets closed'}.','. $sockets{'TCP/IPv6 sockets closed'}.','. $sockets{'UDP/IPv4 socket bind failures'}.','. $sockets{'TCP/IPv4 socket bind failures'}.','. $sockets{'UDP/IPv6 socket bind failures'}.','. $sockets{'TCP/IPv6 socket bind failures'}.','. $sockets{'UDP/IPv4 socket connect failures'}.','. $sockets{'TCP/IPv4 socket connect failures'}.','. $sockets{'UDP/IPv6 socket connect failures'}.','. $sockets{'TCP/IPv6 socket connect failures'}.','. $sockets{'UDP/IPv4 connections established'}.','. $sockets{'TCP/IPv4 connections established'}.','. $sockets{'UDP/IPv6 connections established'}.','. $sockets{'TCP/IPv6 connections established'}.','. $sockets{'TCP/IPv4 connections accepted'}.','. $sockets{'TCP/IPv6 connections accepted'}.','. $sockets{'UDP/IPv4 send errors'}.','. $sockets{'TCP/IPv4 send errors'}.','. $sockets{'UDP/IPv6 send errors'}.','. $sockets{'TCP/IPv6 send errors'}.','. $sockets{'UDP/IPv4 recv errors'}.','. $sockets{'TCP/IPv4 recv errors'}.','. $sockets{'UDP/IPv6 recv errors'}.','. $sockets{'TCP/IPv6 recv errors'}.','. $sockets{'UDP/IPv4 sockets active'}.','. $sockets{'UDP/IPv6 sockets active'}.','. $sockets{'TCP/IPv4 sockets active'}.','. $sockets{'TCP/IPv6 sockets active'}.','. $sockets{'Raw sockets active'}."\n";