#!/usr/bin/perl
# Copyright (C) International Business Machines Corp., 2003
#
# 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 
#
# FILE: au_netlink
#
# PURPOSE: test for aucat/augrep utilities on "NETLINK" audit records
#
# DESCRIPTION:    This test has ip and tc commands embedded in it to generate various
#                 an NETLINK audit records (with the local filter.conf in place).
#                 The Event flags are tested with the NETLINK type.
#                 The NETLINK type specific flags are tested.
#
#                 Then this script runs the following scenarios: (the data is only a sample the 
#                 test actually pulls it from the aucat record found).
#
# aucat | grep RTM_NEWADDR
# augrep -e NETLINK
# augrep --event=NETLINK
# augrep -e NETLINK -G 0
# augrep -e NETLINK --group=0
# augrep -e NETLINK -I 0
# augrep -e NETLINK --dstgroup=0
# augrep -e NETLINK -L 0
# augrep -e NETLINK --netresult=0
# aucat | grep RTM_DELADDR
# aucat | grep RTM_NEWNEIGH
# aucat | grep RTM_DELNEIGH
# aucat | grep RTM_NEWROUTE
# aucat | grep RTM_DELROUTE
# aucat | grep RTM_NEWRULE
# aucat | grep RTM_DELRULE
# aucat | grep RTM_NEWQDISC
# aucat | grep RTM_DELQDISC
# aucat | grep RTM_NEWTCLASS
# aucat | grep RTM_DELTCLASS
# aucat | grep RTM_NEWTFILTER
# aucat | grep RTM_DELTFILTER
#
#
# HISTORY:
#       08/2003 Originated by Niki A. Rahimi <narahimi@us.ibm.com>
#       08/2003 Reviewed and revised by Michael A. Halcrow <mike@halcrow.us>
#       09/2003 Furthered by Kylene J. Smith <kylene@us.ibm.com>

use strict;
require au_params;
require au_utils;

my $filter_dot_conf_fullpath = au_params::filter_dot_conf_fullpath();
my $filter_dot_conf_backup_fullpath = au_params::filter_dot_conf_backup_fullpath();
my $aucat_executable = au_params::aucat_executable();
my $augrep_executable = au_params::augrep_executable();
my $audit_log_fullpath = au_params::audit_log_fullpath();
my $audit_logs_fullpath = au_params::audit_logs_fullpath();
my $audit_log_link_fullpath = au_params::audit_log_link_fullpath();
my $auditd_executable = au_params::auditd_executable();

my @test = ("RTM_NEWADDR", 
	    "RTM_DELADDR",
	    "RTM_NEWNEIGH",
	    "RTM_DELNEIGH",
	    "RTM_NEWROUTE",
	    "RTM_DELROUTE",
	    "RTM_NEWRULE",
	    "RTM_DELRULE",
	    "RTM_NEWQDISC",
	    "RTM_DELQDISC",
	    "RTM_NEWTCLASS",
	    "RTM_DELTCLASS",
	    "RTM_NEWTFILTER",
	    "RTM_DELTFILTER" );

my $aucat_failcount = 0;
my $aucat_successcount = 0;
my $augrep_failcount = 0;
my $augrep_successcount = 0;
my $au_cmd = "";


my $dev = "";
my $mac_arch = `uname -m`;
chomp $mac_arch;

if ( ($mac_arch eq "s390") || ($mac_arch eq "s390x") ) {
	$dev = "eth0";
#	$dev = "iucv0";
}
else {
	$dev = "eth0";
}

sub augrep_results ( \@) {

    my @cat_record = @{$_[0]};

    open(HSI, "$au_cmd |")
	or die "TEST ERROR: Cannot open augrep";

    my @grep_record = <HSI>;
    close(HSI);

    if ( @grep_record == 1  && @grep_record == @cat_record ) {
	print "TEST PASS: $au_cmd\n";
	$augrep_successcount++;
    }
    else {
	print "TEST FAIL: $au_cmd\n";
	$augrep_failcount++;
    }    
}

sub aucat_results ( $ ) {

	sleep(15);

    my $test_number = $_[0]; 
    
    $au_cmd = "$aucat_executable | grep @test[$test_number-1]";

    # wait for the record to get to the log
    sleep 2;

    open(HSI, "$au_cmd |")
	or die "TEST ERROR: Cannot open aucat";

    my @cat_record = <HSI>;
    close(HSI);


    if ( @cat_record == 1 ) {
	print "TEST PASS: $au_cmd\n";
	$aucat_successcount++;
    }
    else {
	print "TEST FAIL: $au_cmd\n";
	$aucat_failcount++;
    }

    return @cat_record;
}


au_utils::preTestSetup();
sleep 10;

my $cmd = "ip addr add 192.168.32.1/24 dev $dev"; 
system($cmd);

my @aucat_records = aucat_results( 1 );


my($timestamp, $seqnr, $pid, $login, $data ) = split(/\s+/, $aucat_records[0], 5);
my($junk, $msg, $junk, $af, $junk, $src, $junk, $dst, $junk, $result) = split(/[;,:=]/, $data, 10);
chomp($result);

#testing event flags with NETLINK type
$au_cmd = "$augrep_executable -e NETLINK";
augrep_results(@aucat_records);


$au_cmd = "$augrep_executable --event=NETLINK";
augrep_results(@aucat_records);

#Testing NETLINK specific flags

#testing Group flags
$au_cmd = "$augrep_executable -e NETLINK -G 0";
augrep_results(@aucat_records);

$au_cmd = "$augrep_executable -e NETLINK --group=0";
augrep_results(@aucat_records);

#testing DSTGroup flags
$au_cmd = "$augrep_executable -e NETLINK -I 0";
augrep_results(@aucat_records);

$au_cmd = "$augrep_executable -e NETLINK --dstgroup=0";
augrep_results(@aucat_records);

#testing Result flags
$au_cmd = "$augrep_executable -e NETLINK -L $result";
augrep_results(@aucat_records);

$au_cmd = "$augrep_executable -e NETLINK --netresult=$result";
augrep_results(@aucat_records);


my $cmd = "ip addr del 192.168.32.1/24 dev $dev"; 
system($cmd);

aucat_results( 2 );

my $cmd = "ip neigh add 192.168.64.1 dev $dev lladdr 0:0:0:0:0:1 nud noarp";
system($cmd);

aucat_results( 3 );

my $cmd = "ip neigh del 192.168.64.1 dev $dev";
system($cmd);

aucat_results( 4 );

my $cmd = "ip route add 192.168.64.0/24 dev $dev";
system($cmd);

aucat_results( 5 );

my $cmd = "ip route del 192.168.64.0/24 dev $dev";
system($cmd);

aucat_results( 6 );

my $cmd = "ip rule add dev $dev from 192.168.64.0/24 table main prio 220";
system($cmd);

aucat_results( 7 );

my $cmd = "ip rule del dev $dev from 192.168.64.0/24";
system($cmd);

aucat_results( 8 );

my $cmd = "tc qdisc add dev $dev root handle 1: prio";
system($cmd);

aucat_results( 9 );

my $cmd = "tc qdisc del dev $dev root";
system($cmd);

aucat_results( 10 );

my $cmd = "tc qdisc add dev $dev root handle 1: cbq bandwidth 100Mbit avpkt 1000 cell 8";
system($cmd); 
my $cmd = "tc class add dev $dev parent 1:0 classid 1:1 cbq bandwidth 100Mbit rate 6Mbit maxburst 20 avpkt 1000";
system($cmd);

aucat_results( 11 );

my $cmd = "tc class del dev $dev classid 1:1";
system($cmd);

aucat_results( 12 );

#Test cleanup
my $cmd = "tc qdisc del dev $dev root";
system($cmd);


my $cmd = "tc qdisc add dev $dev root handle 1: prio";
system($cmd);
my $cmd = "tc filter add dev $dev protocol ip parent 1: prio 1 u32 match ip dport 80 0xffff flowid 1:1";
system($cmd);

aucat_results( 13 );

my $cmd = "tc filter del dev $dev parent 1: prio 1";
system($cmd);

aucat_results( 14 );

#Test Cleanup
my $cmd = "tc qdisc del dev $dev root";
system($cmd);

EXIT:

#Final Output
print ("\n\taucat  netlink results");
print ("\tsuccess count: $aucat_successcount");
print ("\tfail count: $aucat_failcount\n");

print ("\n\taugrep netlink results");
print ("\tsuccess count: $augrep_successcount");
print ("\tfail count: $augrep_failcount\n\n");

print ("TEST PASSED = " . ($aucat_successcount + $augrep_successcount) . ", FAILED = " . ($aucat_failcount + $augrep_failcount) . "\n");

#Final Cleanup
au_utils::postTestCleanup();
