initial commit of file from CVS for e-smith-tinydns on Wed 12 Jul 09:11:00 BST 2023
This commit is contained in:
@@ -0,0 +1 @@
|
||||
53
|
@@ -0,0 +1 @@
|
||||
localhost
|
@@ -0,0 +1 @@
|
||||
enabled
|
1
root/etc/e-smith/db/configuration/defaults/tinydns/type
Normal file
1
root/etc/e-smith/db/configuration/defaults/tinydns/type
Normal file
@@ -0,0 +1 @@
|
||||
service
|
11
root/etc/e-smith/db/configuration/migrate/tinydns_ListenIP
Normal file
11
root/etc/e-smith/db/configuration/migrate/tinydns_ListenIP
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
# $tinydns{ListenIP} must not be set in serveronly mode
|
||||
my $tinydns = $DB->get('tinydns');
|
||||
return unless $tinydns;
|
||||
my $mode = $DB->get_value('SystemMode');
|
||||
return unless $mode;
|
||||
if ($mode eq 'serveronly')
|
||||
{
|
||||
$tinydns->delete_prop("ListenIP");
|
||||
}
|
||||
}
|
30
root/etc/e-smith/db/hosts/migrate/20tinydns
Normal file
30
root/etc/e-smith/db/hosts/migrate/20tinydns
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
use esmith::ConfigDB;
|
||||
my $confdb = esmith::ConfigDB->open_ro;
|
||||
return unless $confdb;
|
||||
|
||||
my $systemname = $confdb->get_value('SystemName');
|
||||
my $domainname = $confdb->get_value('DomainName');
|
||||
return unless $systemname && $domainname; # nothing to do
|
||||
|
||||
my $fqdn = "$systemname.$domainname";
|
||||
|
||||
# Make sure that the ReverseDNS property of the proper name of the server
|
||||
# is set to "yes", unless the $LocalIP has a configured PTR record already.
|
||||
my $self_host = undef;
|
||||
foreach my $host ( $DB->get_all() )
|
||||
{
|
||||
next unless $host->prop('HostType') eq 'Self';
|
||||
if ( $host->{key} eq $fqdn )
|
||||
{
|
||||
$self_host = $host;
|
||||
}
|
||||
if ( $host->prop('ReverseDNS')
|
||||
&& ( $host->prop('ReverseDNS') eq 'yes' ) )
|
||||
{
|
||||
# It already has one configured. Nothing to do.
|
||||
return;
|
||||
}
|
||||
}
|
||||
$self_host->set_prop( 'ReverseDNS', 'yes' ) if $self_host;
|
||||
}
|
0
root/etc/e-smith/events/bootstrap-console-save/.gitignore
vendored
Normal file
0
root/etc/e-smith/events/bootstrap-console-save/.gitignore
vendored
Normal file
0
root/etc/e-smith/events/post-install/.gitignore
vendored
Normal file
0
root/etc/e-smith/events/post-install/.gitignore
vendored
Normal file
0
root/etc/e-smith/events/post-upgrade/.gitignore
vendored
Normal file
0
root/etc/e-smith/events/post-upgrade/.gitignore
vendored
Normal file
4
root/etc/e-smith/templates/var/service/tinydns/env/DATALIMIT
vendored
Normal file
4
root/etc/e-smith/templates/var/service/tinydns/env/DATALIMIT
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
my $datalimit = $tinydns{'DataLimit'} || "300000";
|
||||
"$datalimit";
|
||||
}
|
3
root/etc/e-smith/templates/var/service/tinydns/env/IP
vendored
Normal file
3
root/etc/e-smith/templates/var/service/tinydns/env/IP
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
$OUT = $tinydns{'ListenIP'} || "127.0.0.1";
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
{
|
||||
|
||||
use esmith::HostsDB;
|
||||
$hosts = esmith::HostsDB->open_ro;
|
||||
|
||||
use esmith::DomainsDB;
|
||||
my $ddb = esmith::DomainsDB->open_ro;
|
||||
|
||||
use esmith::util;
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Returns a hash of hostnames with IP addresses as values
|
||||
#--------------------------------------------------------
|
||||
|
||||
sub get_generic_hostentries
|
||||
{
|
||||
#--------------------------------------------------
|
||||
# Compute local IP address, netmask and network values.
|
||||
#--------------------------------------------------
|
||||
|
||||
my $ipaddrBits = esmith::util::IPquadToAddr ($LocalIP);
|
||||
my $netmaskBits = esmith::util::IPquadToAddr ($LocalNetmask);
|
||||
my $networkBits = $ipaddrBits & $netmaskBits;
|
||||
|
||||
#--------------------------------------------------
|
||||
# Compute our hostid, and the highest hostid, limiting range
|
||||
# to a class B at most (so we don't get a huge output file).
|
||||
#--------------------------------------------------
|
||||
|
||||
my $myHostid = (~ $netmaskBits) & $ipaddrBits;
|
||||
|
||||
my $maxHostid = ((~ $netmaskBits) & 0xffffff) - 1;
|
||||
$maxHostid = ($maxHostid <= 65534) ? $maxHostid : 65534;
|
||||
|
||||
my %name2ip;
|
||||
#--------------------------------------------------
|
||||
# Generate A records for the entire local network
|
||||
# We can then override particular entries if we need to
|
||||
# However, multiple A records are not an issue
|
||||
# as long as there is a PTR record pointing to the correct
|
||||
# hostname
|
||||
#--------------------------------------------------
|
||||
|
||||
for ($i = 1; $i <= $maxHostid; $i++)
|
||||
{
|
||||
my $ip = esmith::util::IPaddrToQuad ($networkBits | $i);
|
||||
my $hostname = sprintf ("pc-%.5d", $i);
|
||||
|
||||
$name2ip{$hostname} = $ip;
|
||||
}
|
||||
|
||||
return %name2ip;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Calculates an array of domains that require DNS
|
||||
#--------------------------------------------------------
|
||||
@domains = map { $_->key } $ddb->get_all_by_prop('type' => 'domain');
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Returns an array of domains that require DNS
|
||||
#--------------------------------------------------------
|
||||
sub get_domains { return @domains; }
|
||||
|
||||
sub get_local_domainname { return $DomainName; }
|
||||
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Returns the IP Address of the host in question.
|
||||
#--------------------------------------------------------
|
||||
sub host2ip
|
||||
{
|
||||
my $host = shift;
|
||||
my $ip = undef;
|
||||
die "Host record must have HostType prop!"
|
||||
unless my $hosttype = $host->prop('HostType');
|
||||
|
||||
if ($hosttype eq 'Self')
|
||||
{
|
||||
$ip = $LocalIP;
|
||||
}
|
||||
$ip ||= $host->prop('ExternalIP') || $host->prop('InternalIP');
|
||||
return $ip;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Returns a hash of IPs to hostnames, representing the
|
||||
# chosen hostnames for reverse dns lookups for each IP.
|
||||
#--------------------------------------------------------
|
||||
sub get_reverse_lookup_choices
|
||||
{
|
||||
my %reverse_lookups = ();
|
||||
foreach my $host ($hosts->hosts())
|
||||
{
|
||||
# A remote host must be a DNS alias.
|
||||
next if $host->prop('HostType') eq 'Remote';
|
||||
|
||||
my $alias = $host->prop('ReverseDNS') || "no";
|
||||
if ($alias eq "yes")
|
||||
{
|
||||
# This host is not a DNS alias, so we should make note of it
|
||||
# for reverse DNS lookup purposes.
|
||||
my $ip = host2ip($host);
|
||||
$reverse_lookups{$ip} = $host->{key};
|
||||
# Note: Here we clobber any existing key/value pair, so if
|
||||
# there is more than one host with the same ip flagged as
|
||||
# being the reversedns host, the last one entered in this hash
|
||||
# will win. Don't do that. ;-)
|
||||
}
|
||||
}
|
||||
return %reverse_lookups;
|
||||
}
|
||||
|
||||
$OUT = '';
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
{
|
||||
$OUT .= "# NS Records\n";
|
||||
foreach my $domain (get_domains())
|
||||
{
|
||||
$OUT .= ".$domain:\:$SystemName." . get_local_domainname(). "\n";
|
||||
}
|
||||
|
||||
use esmith::util;
|
||||
# Add name server record for local reverse zone
|
||||
my $reverse =
|
||||
esmith::util::computeLocalNetworkReversed ($LocalIP, $LocalNetmask);
|
||||
$reverse =~ s/\.$//;
|
||||
$OUT .= ".$reverse\:\:127.0.0.1\n";
|
||||
$reverse =
|
||||
esmith::util::computeLocalNetworkReversed ('127.0.0.1', '255.255.255.0');
|
||||
$reverse =~ s/\.$//;
|
||||
$OUT .= ".$reverse\:\:127.0.0.1\n";
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
{
|
||||
$OUT .= "# MX Records\n";
|
||||
foreach my $domain (get_domains())
|
||||
{
|
||||
$OUT .= "\@$domain:\:$SystemName." . get_local_domainname(). "\n";
|
||||
}
|
||||
$OUT .= "\n";
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
{
|
||||
$OUT .= "# A Records for domains\n";
|
||||
foreach my $domain (get_domains())
|
||||
{
|
||||
$OUT .= "+$domain:$LocalIP\n";
|
||||
}
|
||||
$OUT .= "\n";
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
{
|
||||
%allocated_ips = ();
|
||||
foreach my $domain (get_domains())
|
||||
{
|
||||
|
||||
$OUT .= "# A Records for Hosts in $domain\n";
|
||||
foreach my $h ($hosts->get_hosts_by_domain($domain))
|
||||
{
|
||||
my $anIP = host2ip($h);
|
||||
|
||||
my $prefixchar = '+';
|
||||
if ($anIP !~ /^\d+\.\d+\.\d+\.\d+$/)
|
||||
{
|
||||
$prefixchar = 'C';
|
||||
}
|
||||
else
|
||||
{
|
||||
my %reverse_lookups = get_reverse_lookup_choices();
|
||||
# If this IP is spoken for, then we know which host to use for the
|
||||
# reverse DNS lookup PTR.
|
||||
if (exists $reverse_lookups{$anIP})
|
||||
{
|
||||
my $reverse_host = $reverse_lookups{$anIP};
|
||||
if ($reverse_host eq $h->key)
|
||||
{
|
||||
$prefixchar = '=';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# Otherwise, we'll just use the first host that comes along.
|
||||
# Have we picked one already?
|
||||
unless (exists $allocated_ips{$anIP})
|
||||
{
|
||||
$prefixchar = '=';
|
||||
}
|
||||
}
|
||||
# Note that this ip is taken.
|
||||
$allocated_ips{$anIP} = 1;
|
||||
|
||||
}
|
||||
$OUT .= $prefixchar . $h->key . ":$anIP\n";
|
||||
}
|
||||
$OUT .= "\n";
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
{
|
||||
my %name2ip = get_generic_hostentries();
|
||||
|
||||
my $domain = $DomainName;
|
||||
|
||||
$OUT .= "# Generic A Records for $domain\n";
|
||||
foreach (sort keys %name2ip)
|
||||
{
|
||||
$prefixchar = '=';
|
||||
$prefixchar = '+' if exists $allocated_ips{$name2ip{$_}};
|
||||
$OUT .= $prefixchar . "$_.$domain" . ":" . $name2ip{$_} . "\n";
|
||||
}
|
||||
}
|
1
root/service/tinydns
Symbolic link
1
root/service/tinydns
Symbolic link
@@ -0,0 +1 @@
|
||||
/var/service/tinydns
|
15
root/usr/lib/systemd/system/tinydns.service
Normal file
15
root/usr/lib/systemd/system/tinydns.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=tinydns,
|
||||
After=network.target
|
||||
Requires=runit.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/sbin/e-smith/service-status tinydns
|
||||
ExecStart=/usr/bin/sv u /service/tinydns
|
||||
ExecStop=/usr/bin/sv stop /service/tinydns
|
||||
ExecReload=/usr/bin/sv t /service/tinydns
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=sme-server.target
|
0
root/var/log/tinydns/.gitignore
vendored
Normal file
0
root/var/log/tinydns/.gitignore
vendored
Normal file
4
root/var/service/tinydns/control/1
Normal file
4
root/var/service/tinydns/control/1
Normal file
@@ -0,0 +1,4 @@
|
||||
#! /bin/sh
|
||||
|
||||
/sbin/e-smith/expand-template /var/service/tinydns/root/data
|
||||
cd "/var/service/tinydns/root" && /usr/local/bin/tinydns-data
|
57
root/var/service/tinydns/control/2
Normal file
57
root/var/service/tinydns/control/2
Normal file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# copyright (C) 2002-2005 Mitel Networks Corporation
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Technical support for this program is available from Mitel Networks
|
||||
# Please visit our web site www.mitel.com/sme/ for details.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use esmith::ConfigDB;
|
||||
use esmith::util;
|
||||
use esmith::templates;
|
||||
|
||||
my $conf = esmith::ConfigDB->open;
|
||||
#--------------------------------------------------------------
|
||||
# If tinydns is running on the external interface IP,
|
||||
# then update the ListenIP property, expand the IP
|
||||
# config file, and restart the process.
|
||||
#--------------------------------------------------------------
|
||||
|
||||
my $tinydns = $conf->get('tinydns')
|
||||
or die("No tinydns entry in config db\n");
|
||||
my $listen_ip = $tinydns->prop("ListenIP");
|
||||
exit 0 unless defined $listen_ip;
|
||||
|
||||
my $external_ip = $conf->get('ExternalIP')
|
||||
or die("No ExternalIP entry in config db\n");
|
||||
$external_ip = $external_ip->value;
|
||||
exit 0 if ($external_ip eq $listen_ip);
|
||||
|
||||
$tinydns->merge_props('ListenIP' => $external_ip);
|
||||
|
||||
esmith::templates::processTemplate ({
|
||||
TEMPLATE_PATH => "/var/service/tinydns/env/IP",
|
||||
PERMS => 0644,
|
||||
});
|
||||
|
||||
exec "sv", "t", "/service/tinydns" or
|
||||
die "Could not exec sv: $!";
|
0
root/var/service/tinydns/down
Normal file
0
root/var/service/tinydns/down
Normal file
1
root/var/service/tinydns/env/ROOT
vendored
Normal file
1
root/var/service/tinydns/env/ROOT
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/var/service/tinydns/root
|
27
root/var/service/tinydns/log/run
Normal file
27
root/var/service/tinydns/log/run
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# copyright (C) 1999-2003 Mitel Networks Corporation
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Technical support for this program is available from Mitel Networks
|
||||
# Please visit our web site www.mitel.com/sme/ for details.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
exec \
|
||||
/usr/local/bin/setuidgid dnslog \
|
||||
/usr/local/bin/multilog t s5000000 \
|
||||
/var/log/tinydns
|
0
root/var/service/tinydns/root/.gitignore
vendored
Normal file
0
root/var/service/tinydns/root/.gitignore
vendored
Normal file
8
root/var/service/tinydns/run
Normal file
8
root/var/service/tinydns/run
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
exec 2>&1
|
||||
./control/1
|
||||
exec envdir ./env sh -c '
|
||||
exec envuidgid dns \
|
||||
softlimit -d "$DATALIMIT" \
|
||||
/usr/local/bin/tinydns
|
||||
'
|
59
root/var/service/tinydns/tinydns-log.pl
Normal file
59
root/var/service/tinydns/tinydns-log.pl
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/perl -p
|
||||
|
||||
# tinydns log formatting utility
|
||||
# based on Faried Nawaz's logfile formatter for dnscache
|
||||
# by Kenji Rikitake <kenji.rikitake@acm.org> 29-JUL-2000
|
||||
# please put this on dnscache.com ftp site.
|
||||
|
||||
# convert addresses in hex to dotted decimal notation.
|
||||
s/\b([a-f0-9]{8})\b/join(".", unpack("C*", pack("H8", $1)))/eg;
|
||||
|
||||
### clean up some messages
|
||||
# convert stuff like 127.0.0.2:0422:05be to something more descriptive.
|
||||
# query tai64n host:port:qid flag qtype thing
|
||||
# keep tai64n header as is - use tai64nlocal to convert it to TAI
|
||||
|
||||
s/^(@[a-f0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-\I\/]) \b([a-f0-9]+) \b([-.\w]+)/$1." ".printQueryLine($2,$3,$4,$5,$6,$7)/e;
|
||||
|
||||
### subs
|
||||
|
||||
sub printQueryLine {
|
||||
my ($host, $port, $query_id, $flag, $query_type, $query) = @_;
|
||||
|
||||
# pad hostname
|
||||
|
||||
my $ret = "$host:";
|
||||
$ret .= hex($port);
|
||||
$ret .= ":" . hex($query_id);
|
||||
$ret .= " " . $flag;
|
||||
$ret .= " " . queryType(hex($query_type)) . " $query";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub queryType {
|
||||
my ($type) = shift;
|
||||
|
||||
my $ret = "";
|
||||
|
||||
# i only list the ones that are in dnscache's dns.h.
|
||||
SWITCH: {
|
||||
($type == 1) && do { $ret = "a"; last SWITCH; };
|
||||
($type == 2) && do { $ret = "ns"; last SWITCH; };
|
||||
($type == 5) && do { $ret = "cname"; last SWITCH; };
|
||||
($type == 6) && do { $ret = "soa"; last SWITCH; };
|
||||
($type == 12) && do { $ret = "ptr"; last SWITCH; };
|
||||
($type == 13) && do { $ret = "hinfo"; last SWITCH; };
|
||||
($type == 15) && do { $ret = "mx"; last SWITCH; };
|
||||
($type == 16) && do { $ret = "txt"; last SWITCH; };
|
||||
($type == 17) && do { $ret = "rp"; last SWITCH; };
|
||||
($type == 24) && do { $ret = "sig"; last SWITCH; };
|
||||
($type == 25) && do { $ret = "key"; last SWITCH; };
|
||||
($type == 28) && do { $ret = "aaaa"; last SWITCH; };
|
||||
($type == 252) && do { $ret = "axfr"; last SWITCH; };
|
||||
($type == 255) && do { $ret = "any"; last SWITCH; };
|
||||
do { $ret .= "$type "; last SWITCH; };
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
319
root/var/service/tinydns/tinydns-readstats
Normal file
319
root/var/service/tinydns/tinydns-readstats
Normal file
@@ -0,0 +1,319 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# $Id: tinydns-readstats.txt,v 1.9 2005/02/01 14:40:22 nate Exp $
|
||||
#
|
||||
# Formatting functionality adapted from:
|
||||
# tinydns log formatting utility
|
||||
# based on Faried Nawaz's logfile formatter for dnscache
|
||||
# by Kenji Rikitake <kenji.rikitake@acm.org> 29-JUL-2000
|
||||
#
|
||||
# The idea of opening up multilog for writing and sending
|
||||
# log output to it was taken from tinydns-rrd by Ask Bj<42>rn
|
||||
# Hansen, along with a code snippit or two.
|
||||
#
|
||||
# What's left was written by me, Nate Campi <nate@campin.net>
|
||||
##################################################################
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# If you have a high traffic tinydns server leave out the --log
|
||||
# option and pipe to multilog in order to minimize I/O. This is
|
||||
# an example daemontools log run file (e.g. /service/tinydns/log/run):
|
||||
#
|
||||
# #!/bin/sh
|
||||
# exec setuidgid dnslog tinydns-readstats.pl
|
||||
#
|
||||
# If you want pretty logs sent to multilog use the option --logpretty.
|
||||
# To run multilog you need a log run script something like this:
|
||||
#
|
||||
# #!/bin/sh
|
||||
# exec setuidgid dnslog tinydns-readstats.pl --logpretty -- multilog t ./main
|
||||
#
|
||||
# If you simply want to use this script to prettify your logs, use the
|
||||
# --nostats option in your log/run script:
|
||||
#
|
||||
# #!/bin/sh
|
||||
# exec setuidgid dnslog tinydns-readstats.pl --nostats --logpretty -- multilog t ./main
|
||||
#
|
||||
# You can use this with dnscache now as well,just add the --dnscache
|
||||
# option (/service/dnscache/log/run):
|
||||
#
|
||||
# #!/bin/sh
|
||||
# exec setuidgid dnslog tinydns-readstats.pl --dnscache --log -- multilog t ./main
|
||||
#
|
||||
##################################################################
|
||||
#
|
||||
# To query these stats over SNMP use these lines in net-snmp snmpd.conf:
|
||||
#
|
||||
# exec VALUES /bin/echo A PTR ANY MX NS CNAME SOA SRV AAAA TOTAL
|
||||
# exec bindstats /bin/cat /home/zoneaxfr/stats/stats_file
|
||||
#
|
||||
# See http://www.campin.net/DNS/graph.html for the rest of what you need to
|
||||
# graph the stats.
|
||||
#
|
||||
##################################################################
|
||||
#
|
||||
# Hmm, each time I implemented this on a box, the stats file was already
|
||||
# in place and valid from a prototype version of these scripts. I totally
|
||||
# spaced on whether it did the right thing when no file existed, the
|
||||
# script should take some care to make sure things are in order.
|
||||
#
|
||||
# Make sure the file is there, readable, and has some valid values in
|
||||
# it by running UNIX commands like this:
|
||||
#
|
||||
# $ mkdir -p /home/zoneaxfr/stats
|
||||
# $ echo 0 0 0 0 0 0 0 0 0 0 > /home/zoneaxfr/stats/stats_file
|
||||
# $ chown -R dnslog /home/zoneaxfr/stats
|
||||
#
|
||||
# Just be sure that if your logging account isn't named "dnslog" that
|
||||
# you substitute the correct username in the chown command ("Gdnslog"
|
||||
# perhaps).
|
||||
#
|
||||
##################################################################
|
||||
|
||||
use Getopt::Long;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use strict;
|
||||
|
||||
my $stats_file = "/home/zoneaxfr/stats/stats_file";
|
||||
my $stats_file_temp = "/home/zoneaxfr/stats/stats_file.temp";
|
||||
my $stats_flush_interval = 60; # between 60 and 300 seconds is probably best
|
||||
my $time = time();
|
||||
my $stats_flush_time = ( $time + $stats_flush_interval );
|
||||
|
||||
# Scott Middlebrooks <scott DOT middlebrooks AT harrynorman DOT com> had
|
||||
# a problem with zombies, contributed the following to reap them
|
||||
$SIG{CHLD} = \&REAPER;
|
||||
sub REAPER {
|
||||
my $waitedpid;
|
||||
while (($waitedpid = waitpid(-1, &WNOHANG)) > 0) {
|
||||
}
|
||||
$SIG{CHLD} = \&REAPER;
|
||||
}
|
||||
|
||||
my ( $total, $srv, $any, $a, $ns,
|
||||
$cname, $soa, $aaaa, $mx, $ptr,
|
||||
$other, @line,
|
||||
|
||||
$oldtotal, $oldsrv, $oldany, $olda, $oldns,
|
||||
$oldcname, $oldsoa, $oldaaaa, $oldmx, $oldptr,
|
||||
|
||||
$total_a, $total_any, $total_srv, $total_total,
|
||||
$total_ns, $total_soa, $total_cname, $total_aaaa,
|
||||
$total_mx, $total_ptr,
|
||||
) = 0;
|
||||
|
||||
my (
|
||||
$DEBUG, $query_types, %opts, $pid, $i, @stats, $dnscache,
|
||||
);
|
||||
|
||||
|
||||
%opts = ('log' => 0,
|
||||
'logpretty' => 0,
|
||||
'nostats' => 0,
|
||||
'dnscache' => $dnscache,
|
||||
'debug' => $DEBUG,
|
||||
);
|
||||
|
||||
GetOptions (\%opts,
|
||||
'log!',
|
||||
'nostats!',
|
||||
'dnscache!',
|
||||
'logpretty!',
|
||||
'debug!',
|
||||
)
|
||||
or exit 2;
|
||||
|
||||
$DEBUG = $opts{debug};
|
||||
$dnscache = $opts{dnscache};
|
||||
|
||||
die "Can't use both --log and --logpretty at once\n" if $opts{log} and $opts{logpretty};
|
||||
|
||||
if ( $opts{log} || $opts{logpretty} ) { # pipe to multilog
|
||||
|
||||
$| = 1;
|
||||
my $command = join " ", @ARGV;
|
||||
open (MULTI, "|$command") or die "Could not open $command: $!";
|
||||
|
||||
my $oldfh = select MULTI;
|
||||
$| = 1;
|
||||
select $oldfh;
|
||||
}
|
||||
|
||||
while (<STDIN>) {
|
||||
|
||||
$time = time();
|
||||
|
||||
# increment the running total - unless it is a "starting tinydns" line,
|
||||
# I don't know of any other non-query lines, let me know if there are any
|
||||
if ($dnscache) {
|
||||
$total++ if /^query/ ;
|
||||
} else { # then we're running tinydns
|
||||
$total++ unless /starting tinydns/ ;
|
||||
}
|
||||
|
||||
print "INPUT before transformation is $_\n" if $DEBUG;
|
||||
|
||||
print MULTI "$_" if $opts{log}; # output for multilog's pleasure
|
||||
|
||||
unless ($dnscache) {
|
||||
|
||||
# convert addresses in hex to dotted decimal notation.
|
||||
s/\b([a-f0-9]{8})\b/join(".", unpack("C*", pack("H8", $1)))/eg;
|
||||
|
||||
# clean up the rest
|
||||
s/^([\d.]+):(\w+):(\w+) ([\+\-\/]) \b([a-f0-9]+) \b([-.\w]+)/printQueryLine($1,$2,$3,$4,$5,$6)/e;
|
||||
|
||||
print "INPUT after transformation is $_\n" if $DEBUG;
|
||||
|
||||
print MULTI "$_" if $opts{logpretty}; # output in pretty format for multilog's pleasure
|
||||
|
||||
@line = split(/\s+/); # split it for easy parsing
|
||||
|
||||
SWITCH: {
|
||||
if ( $line[2] eq "soa" ) { $soa++; last SWITCH; }
|
||||
if ( $line[2] eq "ptr" ) { $ptr++; last SWITCH; }
|
||||
if ( $line[2] eq "mx" ) { $mx++; last SWITCH; }
|
||||
if ( $line[2] eq "a" ) { $a++; last SWITCH; }
|
||||
if ( $line[2] eq "srv" ) { $srv++; last SWITCH; }
|
||||
if ( $line[2] eq "ns" ) { $ns++; last SWITCH; }
|
||||
if ( $line[2] eq "cname" ) { $cname++; last SWITCH; }
|
||||
if ( $line[2] eq "any" ) { $any++; last SWITCH; }
|
||||
if ( $line[2] eq "aaaa" ) { $aaaa++; last SWITCH; }
|
||||
$other++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !($opts{nostats}) && ($time >= $stats_flush_time) ) { #flush the stats with a child proc
|
||||
|
||||
$stats_flush_time += $stats_flush_interval; # set the time to flush stats again
|
||||
|
||||
$pid = fork();
|
||||
die "Cannot fork: $!" unless defined($pid);
|
||||
if ($pid == 0) {
|
||||
# Child process
|
||||
updateStats();
|
||||
exit(0); # Child process exits when it is done.
|
||||
}
|
||||
|
||||
# clear out the stats now that we've flushed them to disk
|
||||
|
||||
( $total, $srv, $any, $a, $ns,
|
||||
$cname, $soa, $aaaa, $mx, $ptr,
|
||||
$other, @line, ) = 0;
|
||||
|
||||
|
||||
} # else 'tis the parent process, which goes back to processing logs
|
||||
|
||||
}
|
||||
|
||||
|
||||
### subs
|
||||
|
||||
sub printQueryLine {
|
||||
my ($host, $port, $query_id, $flag, $query_type, $query) = @_;
|
||||
|
||||
# pad hostname
|
||||
|
||||
my $ret = "$host:";
|
||||
$ret .= hex($port);
|
||||
$ret .= ":" . hex($query_id);
|
||||
$ret .= " " . $flag;
|
||||
$ret .= " " . queryType(hex($query_type)) . " $query";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub queryType {
|
||||
my ($type) = shift;
|
||||
|
||||
my $ret = "";
|
||||
|
||||
# i only list the ones that are in dnscache's dns.h.
|
||||
SWITCH: {
|
||||
($type == 1) && do { $ret = "a"; last SWITCH; };
|
||||
($type == 2) && do { $ret = "ns"; last SWITCH; };
|
||||
($type == 5) && do { $ret = "cname"; last SWITCH; };
|
||||
($type == 6) && do { $ret = "soa"; last SWITCH; };
|
||||
($type == 12) && do { $ret = "ptr"; last SWITCH; };
|
||||
($type == 13) && do { $ret = "hinfo"; last SWITCH; };
|
||||
($type == 15) && do { $ret = "mx"; last SWITCH; };
|
||||
($type == 16) && do { $ret = "txt"; last SWITCH; };
|
||||
($type == 17) && do { $ret = "rp"; last SWITCH; };
|
||||
($type == 24) && do { $ret = "sig"; last SWITCH; };
|
||||
($type == 25) && do { $ret = "key"; last SWITCH; };
|
||||
($type == 28) && do { $ret = "aaaa"; last SWITCH; };
|
||||
($type == 252) && do { $ret = "axfr"; last SWITCH; };
|
||||
($type == 255) && do { $ret = "any"; last SWITCH; };
|
||||
do { $ret .= "$type "; last SWITCH; };
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub updateStats {
|
||||
|
||||
sysopen(STATS_FILE,"$stats_file", O_RDWR|O_CREAT) ||
|
||||
die "Sorry, I couldn't open $stats_file for writing: $!\n";
|
||||
|
||||
flock(STATS_FILE, LOCK_EX)
|
||||
or die "Can't write-lock $stats_file: $!\n";
|
||||
|
||||
sysopen(STATS_FILE_TEMP,"$stats_file_temp", O_RDWR|O_CREAT) ||
|
||||
die "Sorry, I couldn't open $stats_file_temp for writing: $!\n";
|
||||
|
||||
flock(STATS_FILE_TEMP, LOCK_EX)
|
||||
or die "Can't write-lock $stats_file_temp: $!\n";
|
||||
|
||||
while (<STATS_FILE>) {
|
||||
chomp;
|
||||
@stats = split(/\s+/); # split it for easy parsing
|
||||
|
||||
$olda = $stats[0];
|
||||
$oldptr = $stats[1];
|
||||
$oldany = $stats[2];
|
||||
$oldmx = $stats[3];
|
||||
$oldns = $stats[4];
|
||||
$oldcname = $stats[5];
|
||||
$oldsoa = $stats[6];
|
||||
$oldsrv = $stats[7];
|
||||
$oldaaaa = $stats[8];
|
||||
$oldtotal = $stats[9];
|
||||
}
|
||||
|
||||
print "oldA oldPTR oldANY oldMX oldNS oldCNAME oldSOA oldSRV oldAAAA oldTOTAL\n" if $DEBUG;
|
||||
print "$olda $oldptr $oldany $oldmx $oldns $oldcname $oldsoa $oldsrv $oldaaaa $oldtotal\n" if $DEBUG;
|
||||
|
||||
print "A PTR ANY MX NS CNAME SOA SRV AAAA TOTAL\n" if $DEBUG;
|
||||
print "$a $ptr $any $mx $ns $cname $soa $srv $aaaa $total\n" if $DEBUG;
|
||||
|
||||
$total_a = ( $olda + $a );
|
||||
$total_ptr = ( $oldptr + $ptr );
|
||||
$total_any = ( $oldany + $any );
|
||||
$total_any = ( $oldany + $any );
|
||||
$total_mx = ( $oldmx + $mx );
|
||||
$total_ns = ( $oldns + $ns );
|
||||
$total_cname = ( $oldcname + $cname );
|
||||
$total_soa = ( $oldsoa + $soa );
|
||||
$total_srv = ( $oldsrv + $srv );
|
||||
$total_aaaa = ( $oldaaaa + $aaaa );
|
||||
$total_total = ( $oldtotal + $total );
|
||||
|
||||
# be careful and truncate it
|
||||
seek(STATS_FILE_TEMP, 0, 0) or die "can't rewind numfile : $!";
|
||||
truncate(STATS_FILE_TEMP, 0) or die "can't truncate $stats_file: $!";
|
||||
|
||||
print STATS_FILE_TEMP "$total_a $total_ptr $total_any $total_mx $total_ns $total_cname $total_soa $total_srv $total_aaaa $total_total\n";
|
||||
|
||||
rename("$stats_file_temp","$stats_file") || die "Can't rename $stats_file_temp to $stats_file: $!";
|
||||
|
||||
close(STATS_FILE);
|
||||
close(STATS_FILE_TEMP);
|
||||
|
||||
print "$total_a $total_ptr $total_any $total_mx $total_ns $total_cname $total_soa $total_srv $total_aaaa $total_total\n" if $DEBUG;
|
||||
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user