#! @PERL@ -w # vim:syntax=perl use strict; use lib '@LR_PERL5LIBDIR@'; use Lire::DlfSchema; use Lire::Time; use Lire::Program qw( :msg :dlf ); use Lire::Config; init_dlf_converter( "dns" ); my $schema = eval { Lire::DlfSchema::load_schema( "dns" ) }; lr_err( "failed to load dns schema: $@" ) if $@; my $dlf_maker = $schema->make_hashref2asciidlf_func( qw/time requesting_host request type resolver/ ); # If the user is running tinydns then they should (had to) # have installed the deamontools and ucspi packages. Those # packages provide the tai64nlocal binary that is used to # convert djb's timestamps to human readable form. my $tai64nlocal = Lire::Config->get('tai64nlocal_name'); # tinydns defines these types only my %dns_type = ( 1 => "a", 2 => "ns", 5 => "cname", 6 => "soa", 12 => "ptr", 13 => "hinfo", 15 => "mx", 16 => "txt", 17 => "rp", 24 => "sig", 25 => "key", 28 => "aaaa", 38 => "a6", 252 => "axfr", 255 => "any", ); sub parse_query { my ( $line ) = @_; my %dlf = (); my ( $tai64, $requestee, $auth, $type, $requested ); # @400000000000000000000000 00000000:0000:0000 + 001c slashdot.org ( $tai64, $requestee, $auth, $type, $requested, ) = $line =~ m!^ (@[0-9a-f]+)\s ([0-9a-f:]+)\s (\+|\-)\s ([0-9a-f]{4})\s (.*)\s*? $!x or die "tinydns lexer failed\n"; # FIXME check for errors here my $tai = `echo $tai64 | $tai64nlocal`; my ( $year, $month, $day, $time ); ( $year, $month, $day, $time, ) = $tai =~ m!^ (\d{4})\- (\d{2})\- (\d{2})\s ([\d+:]+) \.\d+ $!x or die "tai64nlocal lexer failed\n"; $dlf{time} = date2cal( $year, $month, $day, $time ); $dlf{resolver} = $auth eq '+' ? 'nonrec' : 'recurs'; die "dns type \'$type\' is not defined by tinydns\n" unless defined $dns_type{hex($type)}; $dlf{type} = $dns_type{hex($type)}; my $ip = (split(/:/, $requestee))[0]; $dlf{requesting_host} = join(".", unpack("C*", pack("H8", $ip))); $dlf{request} = $requested; $dlf_maker->( \%dlf ); } unless ( defined $tai64nlocal) { lr_err( qq{tai64nlocal binary does not exist on host system, skipping} ); } my $lines = 0; my $dlflines = 0; my $errorlines = 0; while (<>) { chomp; $lines++; next unless ($_ =~ m!^@!); # every valid line begins with an @ symbol for the TAI eval { my $dlf = parse_query( $_ ); print join( " ", @$dlf), "\n"; $dlflines++; }; if ( $@ ) { lr_warn( $@ ); lr_notice( qq{cannot convert line $. "$_" to dns dlf, skipping} ); $errorlines++; } } end_dlf_converter( $lines, $dlflines, $errorlines ); __END__ =pod =head1 NAME tinydns2dlf - convert tinydns logs, as created by multilog, to dlf =head1 SYNOPSIS B =head1 DESCRIPTION This script converts each line in a tinydns(1) query log, with timestamps as created by multilog(1) to a dns dlf record. tinydns is part of djbdns. multilog is part of daemontools. Logging data is printed automatically by tinydns. A typical line in a log file would look like this: @400000003e67eeb414752ccc 7f000001:eb9f:80bd + 0001 www.slashdot.org =head1 EXAMPLES To process a log as produced by tinydns: $ tai64nfraq < current | tinydns2dlf tinydns2dlf will be rarely used on its own, but is more likely called by lr_log2report: $ lr_log2report tinydns < /service/tinydns/log/main/current =head1 SEE ALSO bind9_query2dlf(1), qmail2dlf(1) http://cr.yp.to/djbdns.html http://cr.yp.to/daemontools.html =head1 VERSION $Id: tinydns2dlf.in,v 1.8 2006/07/23 13:16:33 vanbaal Exp $ =head1 COPYRIGHT Copyright (C) 2003 Christopher Boumenot 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 (see COPYING); if not, check with http://www.gnu.org/copyleft/gpl.html. =head1 AUTHOR Christopher Boumenot =cut # Local Variables: # mode: cperl # End: