package Lire::Firewall::IpchainsDlfConverter;

use strict;

use Lire::DlfConverter;
use Lire::Firewall qw/firewall_number2names/;
use Lire::Syslog;
use Carp;

use base qw/Lire::DlfConverter/;


my %action2cisco = (
    'DENY'   => 'denied',
    'REJECT' => 'denied',
    'ACCEPT' => 'permitted'
);

my @chain_fields = qw/rule action rcv_intf protocol from_ip from_port
    to_ip to_port length tos seq_no fragment ttl/;

sub new {
    my $proto = shift;
    bless {}, (ref $proto || $proto);
}

sub name { 'ipchains' }
sub title { 'IPchains firewall log' }
sub description { '<para>IPchains firewall log</para>' }
sub schemas { qw/firewall/ }

sub handle_log_lines { 1 }

sub init_dlf_converter {
    my ($self, $process) = @_;

    $self->{'parser'} = new Lire::Syslog;
}

sub process_log_line {
    my ($self, $process, $line) = @_;

    #
    # skip invalid log entries before parsing
    #
    return $process->ignore_log_line($line)
        unless $line =~ /Packet log: /;

    eval {
        my $log = $self->{'parser'}->parse($line);
        local $_ = $log->{'content'};
        #
        # skip invalid log entries
        #
        return $process->ignore_log_line($line)
            unless /^Packet log: /;

        my @chain_infos =
        $log->{'content'} =~ /^Packet\slog:\s
            ([-\w]+)\s   # chain
            (\w+)\s     # action
            (\w+)\s     # interface
            PROTO=(\d+)\s # protocol
            (\d+\.\d+\.\d+\.\d+):(\d+)\s # from
            (\d+\.\d+\.\d+\.\d+):(\d+)\s # to
            L=(\d+)\s       # length
            S=(0x[0-9A-Fa-z]+)\s # TOS
            I=(\d+)\s       # Sequence number
            F=(0x[0-9A-Fa-z]+)\s # Fragment offset
            T=(\d+)\s    # TTL
            (.*)$/x     # Other stuff
        or die "ipchains lexer failed\n";

        #
        # assign log values to hash
        #
        my %dlf = (
            'time' => $log->{'timestamp'},
            'count' => 1,
        );

        my $i = 0;
        foreach my $f (@chain_fields) {
            $dlf{$f} = $chain_infos[$i++];
        }

        if(exists $action2cisco{$dlf{'action'}}) {
            $dlf{'action'} = $action2cisco{$dlf{'action'}};
        }

        #
        # convert numbers to names and create dlf-record
        #
        firewall_number2names(\%dlf);
        $process->write_dlf('firewall', \%dlf);
    };

    if($@) {
        $process->error($line, $@);
    }
}

sub finish_conversion {
    delete $_[0]->{'parser'};
}

1; # nag nag.

__END__

=pod

=head1 NAME

Lire::Firewall::IpchainsDlfConverter - convert Ipchains logs to firewall DLF

=head1 DESCRIPTION

B<Lire::Firewall::IpchainsDlfConverter> converts Ipchains logs into
firewall DLF format.
Input for this converter is the standard IPchains syslog log file.

=head1 AUTHOR

Francis J. Lacoste <flacoste@logreport.org>,
Wessel Dankers <wsl@logreport.org>

=head1 VERSION

$Id: IpchainsDlfConverter.pm,v 1.10 2006/07/23 13:16:35 vanbaal Exp $

=head1 COPYRIGHT

Copyright (C) 2001-2003 Stichting LogReport Foundation LogReport@LogReport.org

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.

=cut

# Local Variables:
# mode: cperl
# End:
