#! /usr/bin/perl -w

# vim:syntax=perl

use strict;
use lib '/usr/local/share/perl5';
use Lire::DlfSchema;
use Lire::Syslog;
use Lire::Firewall qw/ firewall_number2names /;
use Lire::Program qw( :msg :dlf );

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

init_dlf_converter( "firewall" );
my $schema	= Lire::DlfSchema::load_schema( "firewall" );
my $dlf_maker	=
  $schema->make_hashref2asciidlf_func( qw/time action protocol
					  from_ip from_port rcv_intf
					  to_ip to_port length rule count /);

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

my $lines      = 0;
my $dlflines   = 0;
my $errorlines = 0;
my $parser     = new Lire::Syslog;
while (<>) {
    chomp;
    $lines++;

    eval {
	my $log = $parser->parse( $_ );

	# Skip non-ipchains records
	#
	# We cannot rely on the process name (usually kernel) since
	# this is added by klogd and not by the ipchains logging code.
	return unless $log->{content} =~ /^Packet log: /;

	my %dlf = ( time => $log->{timestamp} );

	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";

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

	$dlf{action}   = $action2cisco{$dlf{action}} || $dlf{action};
	$dlf{count}    = 1;

	firewall_number2names( \%dlf );

	my $dlf = $dlf_maker->( \%dlf );

	print join( " ", @$dlf), "\n";
	$dlflines++;
    };
    if ($@) {
	lr_warn( $@ );
	lr_notice( qq{cannot convert line $. "$_" to firewall dlf, skipping} );
	$errorlines++;
    }
}

end_dlf_converter( $lines, $dlflines, $errorlines );

__END__

=pod

=head1 NAME

ipchains2dlf - convert ipchains syslog logs to firewall DLF

=head1 SYNOPSIS

B<ipchains2dlf> I<file>

=head1 DESCRIPTION

B<ipchains2dlf> converts Linux 2.2 packet log into firewall DLF format.

=head1 SEE ALSO

The Netfilter webpage at http://netfilter.samba.org/ .

=head1 AUTHORS

Francis J. Lacoste <flacoste@logreport.org>

=head1 VERSION

$Id: ipchains2dlf.in,v 1.8 2002/08/17 00:11:22 flacoste Exp $

=head1 COPYRIGHT

Copyright (C) 2001 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 or write to the Free Software 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.

=cut

# Local Variables:
# mode: cperl
# End:
