From 6165b51cd290154717fac7cd65b1efe36d5336be Mon Sep 17 00:00:00 2001 From: stransky Date: Thu, 7 Feb 2002 09:32:50 +0100 Subject: [PATCH] grosse mise jour darcs-hash:20020207083250-a279a-8b385c6ade091c34835319ecf9e9cddb026bf9bb.gz --- analyse.pl | 573 ++++++++++++++++++++++++++++------------------------- 1 file changed, 300 insertions(+), 273 deletions(-) diff --git a/analyse.pl b/analyse.pl index 32040e2c..39f60db0 100755 --- a/analyse.pl +++ b/analyse.pl @@ -2,16 +2,14 @@ ## ## Analyse.pl ## -## Made by Tab +## Made by Vincent HANQUEZ ## ## Started on Tue 09 Oct 2001 01:28:25 AM CEST tab -## Last Update mer 30 jan 2002 19:56:00 CET Nicolas STRANSKY -## +## Last Update jeu 07 fév 2002 08:47:59 CET Nicolas STRANSKY ## ## 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. +## the Free Software Foundation; only version 2 of the License ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -24,214 +22,229 @@ ## ## ## AUTEUR: Tab -## MAINTAINERS: Nico, Tab +## MAINTAINERS: Tab, Nicolas STRANSKY ## ## DESCRIPTION: analyse permet de creer des resumes des fichiers de ## log cree par net-acct. Net-acct est un daemon qui permet de logguer toutes ## les connexions effectues. ## -## SYNOPSIS: analyse (-d|-u) [-h ] [-m ] [-n ] [-f ] +## SYNOPSIS: analyse [-d] [-h ][-m ][-n ][-f ] +## +## VERSION: 0.35 ## -## VERSION: 0.2 ## use strict; -use IO::Socket; +use File::stat; +use POSIX qw(strftime); +use AppConfig qw(:expand :argcount); +require Mail::Send; -my $inputfile = "/var/log/net-acct/net-acct.log.0"; -my $host = ""; -my $download = 0; -my $nombre_line_affiche = -1; -my $dns_resolve = 1; my $ip_interne = "138\.231\.1(3[6-9]|4[0-3])\."; +## Do not modify after + +my $VERSION = 0.35; +my $AUTEUR = "Vincent HANQUEZ (aka Tab)"; + +my $pattern_ip = + "[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}"; + +my ($opt_download, $opt_upload) = 0; +my $opt_dnsresolve = 1; +my $opt_normalize = 1; +my $opt_config = 1; +my $opt_file = "/var/log/net-acct/net-acct.log.0"; +my $opt_configfile = "/etc/analyse.conf"; +my $opt_host = ""; +my $opt_mail = ""; +my $opt_number = -1; +my $bad_arg = 0; +$opt_upload = 1; + ######## ERROR GEST ######## # USAGE: affiche en cas d'erreur dans les arguments. sub usage { -print "Usage:\tanalyse (-d) [-h ][-m ][-n ][-f ]\n\n"; + print "Usage:\tanalyse (-d) [-h ][-m ][-n ][-f ]\n\n"; -print "\t-d, --download\tTri la base sur le download\n"; -print "\t-h, --host\tResume des connexions effectues par la machine \n"; -print "\t-n, --nombre\tChoisi le nombre de lignes affichees\n"; -print "\t-f, --file\tSpecifie le fichier qui sera analyse\n"; -print "\t --nodns\tNe resout pas les noms DNS\n"; -print "\t --help\tAffiche cette aide\n"; -print "\n"; -print "par defaut si l'option n'existe pas:\n"; -print "\tdownload = on tri sur l'upload\n"; -print "\tnombre = tout est affiche\n"; -print "\tfile = analyse de /var/log/net-acct/net-acct.log.0\n"; + print "\t-d, --download\tTri la base sur le download\n"; + print "\t-h, --host\tResume des connexions effectues par la machine \n"; + print "\t-n, --nombre\tChoisi le nombre de lignes affichees\n"; + print "\t-m, --mail\tEnvoie la sortie par mail a \n"; + print "\t-f, --file\tSpecifie le fichier qui sera analyse\n"; + print "\t-c, --config\tSpecifie le fichier de configuration\n"; + print "\t --nodns\tNe resout pas les noms DNS\n"; + print "\t --nonorm\tNe transforme pas les nombres en forme plus lisible (Ko, Mo, Go)\n"; + print "\t --today\tChiffres du jour, analyse de /var/log/net-acct/net-acct.log\n"; + print "\t --noconfig\tNe charge pas les options du fichier de config\n"; + print "\t --help\tAffiche cette aide\n"; + print "\n"; + print "par defaut si l'option n'est pas utilise:\n"; + print "\tdownload = on tri sur l'upload\n"; + print "\tnombre = tout est affiche\n"; + print "\tfile = analyse de /var/log/net-acct/net-acct.log.0\n"; + print "\tconfig = par defaut /etc/analyse.conf"; -exit (1); + exit (1); } +# SETOPT: gerer les options.. +sub setopt +{ + my ($opt_name, $opt_param) = @_; + if ($opt_name =~ /f/) + { $opt_file = $opt_param; } + elsif ($opt_name =~ /h/) + { $opt_host = $opt_param; } + elsif ($opt_name =~ /n/) + { $opt_number = $opt_param; } + elsif ($opt_name =~ /c/) + { $opt_configfile = $opt_param; } + elsif ($opt_name =~ /m/) + { $opt_mail = $opt_param; } +} + +# Readconfig + +sub read_configfile +{ + my $info = stat($opt_configfile) || die("Unable to open $opt_configfile"); + my $config = AppConfig->new( + 'normalize', + 'dnsresolve', + 'network' => { ARGCOUNT => 1 } + ); + $config->file($opt_configfile); + $opt_normalize = $config->normalize(); + $opt_dnsresolve = $config->dnsresolve(); + $ip_interne = $config->network(); +} + + +########## FCT ########### +# SHOW_ALL: affiche toutes les machines + sub show_all { - my $id; - my %up_db; - my %down_db; - my $max; - - my ($nb_to_print, $sort_by_upload) = @_; - - open INPUT, $inputfile; - while (my $line = ) { - my ($src_ip, $dst_ip, $size) = (split "\t", $line)[2,4,6]; - if ($src_ip =~ /$ip_interne/ ) { - $up_db{$src_ip} += $size; - } - if ($dst_ip =~ /$ip_interne/ ) { - $down_db{$dst_ip} += $size; - } - } - close(INPUT); - - if ($nb_to_print == -1) - { $nb_to_print = (my @nb = (keys %up_db)); } - - $max = (keys %up_db)[0]; - if ($sort_by_upload) { - for (my $dec=$nb_to_print; $dec > 0; $dec--) { - foreach my $ip (keys %up_db) { - if ($up_db{$max} <= $up_db{$ip}) - { $max = $ip; } - } - print normalize($up_db{$max})." (".normalize($down_db{$max}).")\t".ip_to_name($max)."\n" if $up_db{$max} > 0; - $up_db{$max} = 0; - } - } else { - for (my $dec=$nb_to_print; $dec > 0; $dec--) { - foreach my $ip (keys %down_db) { - if ($down_db{$max} <= $down_db{$ip}) - { $max = $ip; } - } - print normalize($down_db{$max})." (".normalize($up_db{$max}). - ")\t".ip_to_name($max)."\n" if $down_db{$max} > 0; - $down_db{$max} = 0; - } - } + my %db; + + my ($nb_to_print, $sort_by_upload) = @_; + +# creation de la base + open (INPUT, $opt_file) || die ("Unable to open $opt_file"); + while (my $line = ) { + my ($src_ip, $dst_ip, $size) = (split "\t", $line)[2,4,6]; + if ($src_ip =~ /$ip_interne/ ) + { $db{$src_ip}->{up} += $size; } + if ($dst_ip =~ /$ip_interne/ ) + { $db{$dst_ip}->{down} += $size; } + } + close(INPUT); + +# Nombre d'entree a afficher + if ($nb_to_print == -1) + { $nb_to_print = (my @nb = (keys %db)); } + + my $max = (keys %db)[0]; + +# tris sur upload ou download + my $way1 = "up"; + my $way2 = "down"; + if ($sort_by_upload == 0) + { $way1 = "down"; $way2 = "up"; } + +# on affiche $nb_to_print entree, en ayant trier les machines + for (my $dec = $nb_to_print; $dec > 0; $dec--) + { + foreach my $ip (keys %db) + { + if (defined($db{$ip}->{$way1}) && + $db{$max}->{$way1} <= $db{$ip}->{$way1}) + { $max = $ip; } + } + print normalize($db{$max}->{$way1})." (". + normalize($db{$max}->{$way2}).")\t". + ip_to_name($max)."\n" if ($db{$max}->{$way1} > 0); + $db{$max}->{$way1} = 0; + } } +############################# +# GET_HOST_INFO: Affiche les informations sur une machine sub get_host_info { - my $up_size = 0; - my $down_size = 0; - my %up_loc_db; - my %down_loc_db; - my %up_dist_db; - my %down_dist_db; - my $max; - my ($ip_search) = @_; - open INPUT, $inputfile; - - while (my $line = ) { - my ($src_ip, $src_port, $dst_ip, $dst_port, $size) = - (split "\t", $line)[2,3,4,5,6]; - if ($src_ip eq $ip_search) { - $up_size += $size; - $up_loc_db{$src_port} += $size; - $up_dist_db{$dst_port} += $size; - } - if ($dst_ip eq $ip_search) { - $down_size += $size; - $down_loc_db{$dst_port} += $size; - $down_dist_db{$src_port} += $size; - } - } - close(INPUT); + my $total_size; + my %db; + my ($ip_search) = @_; - print "--- Info for $ip_search ---"; - print "\n "; - print "\nUpload: \t".normalize($up_size); - print "\nPorts locaux: "; - $max = (keys %up_loc_db)[0]; - for (my $dec=5; $dec > 0; $dec--) { - foreach my $port (keys %up_loc_db) { - if ($up_loc_db{$max} <= $up_loc_db{$port}) - { $max = $port; } - } - print "$max(".normalize($up_loc_db{$max}).") " - if ($up_loc_db{$max} > 0); - $up_loc_db{$max} = 0; - } - print "\nPorts distants: "; - $max = (keys %up_dist_db)[0]; - for (my $dec=5; $dec > 0; $dec--) { - foreach my $port (keys %up_dist_db) { - if ($up_dist_db{$max} <= $up_dist_db{$port}) - { $max = $port; } + $total_size->{UPLOAD} = 0; $total_size->{DOWNLOAD} = 0; + +# Must unresolve name + if (!($ip_search =~ /$pattern_ip/)) + { $ip_search = name_to_ip($ip_search); if ($ip_search eq "0") { return (-1); } } + +# create db + open (INPUT, $opt_file) || die ("Unable to open $opt_file"); + while (my $line = ) { + my ($src_ip, $src_port, $dst_ip, $dst_port, $size) = + (split "\t", $line)[2,3,4,5,6]; + if ($src_ip eq $ip_search) { + $total_size->{UPLOAD} += $size; + $db{$src_port}->{UPLOAD_LOCAL} += $size; + $db{$dst_port}->{UPLOAD_DIST} += $size; + } + if ($dst_ip eq $ip_search) { + $total_size->{DOWNLOAD} += $size; + $db{$dst_port}->{DOWNLOAD_LOCAL} += $size; + $db{$src_port}->{DOWNLOAD_DIST} += $size; } - print "$max(".normalize($up_dist_db{$max}).") " - if ($up_dist_db{$max} > 0); - $up_dist_db{$max} = 0; + } + close (INPUT); + +# printing info + print "--- Info for $ip_search ---"; + print "\n"; + + foreach my $type ("UPLOAD", "DOWNLOAD") + { + print $type.": \t".normalize($total_size->{$type})."\n"; + foreach my $location ("LOCAL", "DIST") + { + print "PORT $location: "; + + my $max = (keys %db)[0]; + for (my $dec=5; $dec > 0; $dec--) { + foreach my $port (keys %db) { + if (defined($db{$port}->{$type."_".$location}) && + (! defined($db{$max}->{$type."_".$location}) || + $db{$max}->{$type."_".$location} <= + $db{$port}->{$type."_".$location})) + { $max = $port; } + } + print "$max(".normalize($db{$max}->{$type."_".$location}).") " + if ($db{$max}->{$type."_".$location} > 0); + $db{$max} ->{$type."_".$location} = 0; + } + print "\n"; + } + print "\n"; } - - print "\n "; - print "\nDownload:\t".normalize($down_size); - print "\nPorts locaux: "; - $max = (keys %down_loc_db)[0]; - for (my $dec=5; $dec > 0; $dec--) { - foreach my $port (keys %down_loc_db) { - if ($down_loc_db{$max} <= $down_loc_db{$port}) - { $max = $port; } - } - print "$max(".normalize($down_loc_db{$max}).") " - if ($down_loc_db{$max} > 0); - $down_loc_db{$max} = 0; + print "--- Calculs ---\n"; + print "Upload pur:\t". + normalize($total_size->{UPLOAD} - $total_size->{DOWNLOAD}/20); + foreach my $type ("UPLOAD", "DOWNLOAD") + { + print "\nTAUX $type:\t"; + print normalize($total_size->{$type}/24)."/h - "; + print normalize($total_size->{$type}/1440)."/min - "; + print normalize($total_size->{$type}/86400)."/s"; } - - print "\nPorts distants: "; - $max = (keys %down_dist_db)[0]; - for (my $dec=5; $dec > 0; $dec--) { - foreach my $port (keys %down_dist_db) { - if ($down_dist_db{$max} <= $down_dist_db{$port}) - { $max = $port; } - } - print "$max(".normalize($down_dist_db{$max}).") " - if ($down_dist_db{$max} > 0); - $down_dist_db{$max} = 0; - } - print "\n "; - print "\n--- Quelques Calculs (Purement Informatif) ---"; - print "\nUpload pur:\t".normalize($up_size - $down_size/20); - print "\nTaux download:\t"; - print normalize($down_size/24)."/h - "; - print normalize($down_size/1440)."/min - "; - print normalize($down_size/86400)."/s"; - print "\nTaux upload:\t"; - print normalize($up_size/24)."/h - "; - print normalize($up_size/1440)."/min - "; - print normalize($up_size/86400)."/s"; - print "\n\nCategoria:\t".categorie($up_size, $down_size); - print "\n(info: 20 mo download = 1 mo upload)"; + print "\n"; } -#sub get_db_for_host -#{ -# open INPUT, $inputfile; -# my $id_port; -# my $id_ip; -# -# my ($host) = @_; -# -# print "--- Info $host ---\n"; -# -# if ($option_get_upload == 1) -# { $id_ip = 2; $id_port = 3; } -# else -# { $id_ip = 4; $id_port = 3; } -# -# while (my $line = ) { -# my ($ip, $port, $size) = (split "\t", $line)[$id_ip,$id_port,6]; -# if ($ip =~ $host) { -# $db{$port} += $size; -# } -# } -#} - ########################### ######### TOOLKIT ######### # normalize: transforme un nombre, en un nombre suivi d'un prefixe @@ -239,116 +252,130 @@ sub get_host_info sub normalize { - my ($nb) = @_; - if (defined $nb) { - if ($nb < 0) - { return ("0o"); } - if ($nb > (1024*1024*1024)) - { return ((int($nb*100/(1024*1024*1024))/100)."Go"); } - elsif ($nb > (1024*1024)) - { return (int($nb/(1024*1024))."Mo"); } - elsif ($nb > 1024) - { return (int($nb/(1024))."Ko"); } - else - { return ($nb."o"); } - } - - return ("0o"); + my ($nb) = @_; + if ($opt_normalize) + { + if (defined $nb) { + if ($nb < 0) + { return ("0o"); } + if ($nb > (1024*1024*1024)) + { return ((int($nb*100/(1024*1024*1024))/100)."Go"); } + elsif ($nb > (1024*1024)) + { return (int($nb/(1024*1024))."Mo"); } + elsif ($nb > 1024) + { return (int($nb/(1024))."Ko"); } + else + { return ($nb."o"); } + } + return ("0"); + } else + { + if (defined $nb) + { return ($nb); } + else + { return (0); } + } } # ip_to_name: resout le nom associe a l'ip donne en argument - sub ip_to_name { - my ($ip) = @_; - my $ret; - my $host_name; - my $aliases; - my $addrtype; - my $length; - my @addrs; + my ($ip) = @_; + my $ret; + my $host_name; + my $aliases; + my $addrtype; + my $length; + my @addrs; - if ($dns_resolve) { - my $ipaddr = pack("C4", split(/\./, $ip)); - if (($host_name, $aliases, $addrtype, $length, @addrs) - = gethostbyaddr($ipaddr, 2)) { - return ($host_name); - } else - { return ("$ip [lookup failed]"); } - } - return ($ip); + if (!($ip =~ /$pattern_ip/)) + { return ($ip); } + + if ($opt_dnsresolve) { + my $ipaddr = pack("C4", split(/\./, $ip)); + if (($host_name, $aliases, $addrtype, $length, @addrs) + = gethostbyaddr($ipaddr, 2)) + { return ($host_name); } + else + { return ("$ip [lookup failed]"); } + } + return ($ip); } -sub categorie +# name_to_ip: deresout le nom +sub name_to_ip { - my $upload_pure; - my ($upload, $download) = @_; - - $upload_pure = $upload - $download/20; - - if ($upload_pure < 200*1024*1024) - { return ("OK"); } - if ($upload_pure < 300*1024*1024) - { return ("Avertissement"); } - if ($upload_pure < 1000*1024*1024) - { return ("Deconnexion 2 semaines"); } - if ($upload_pure < 3000*1024*1024) - { return ("Deconnexion 1 mois"); } - return ("Adios"); + my ($host) = @_; + my $line = ""; + if ($host =~ /$pattern_ip/) + { return ($host); } + open (COM, "host $host | awk '{print \$3}' |"); + $line = ; + close (COM); + if (! ($line =~ /$pattern_ip/)) + { print "host $host don't exist aborting\n"; return ("0");} + chomp($line); + return ($line); } -# print_host_info: on affiche $nb (@_) ports pour l'hote. -#sub print_host_info -#{ -# my ($nb) = @_; -# my $max; -# -# if ($nb == -1) -# { $nb = (my @nb = (keys %db)); } -# -# for (my $dec=$nb; $dec > 0; $dec--) { -# foreach my $port (keys %db) { -# if ($db{$max} <= $db{$port}) -# { $max = $port; } -# } -# print "port $max:\t".normalize($db{$max})."\n" -# if ($db{$max} > 0); -# $db{$max} = 0; -# } -#} +########################################################################## -########################### -########## MAIN ########### +# Lit les options de la ligne de commande +use Getopt::Long; +Getopt::Long::config ("bundling"); +Getopt::Long::GetOptions +( + 'v|version' => sub { print "analyse version $VERSION\n$AUTEUR\n"; }, + 'd|download' => sub { $opt_download = 1; $opt_upload = 0; }, + 'u|upload' => sub { $opt_upload = 1; $opt_download = 0; }, + 'c|config=s' => \&setopt, + 'h|host=s' => \&setopt, + 'f|file=s' => \&setopt, + 'm|mail=s' => \&setopt, + 'n|number=s' => \&setopt, + 'help' => \&usage, + 'nodns' => sub { $opt_dnsresolve = 0; }, + 'nonorm' => sub { $opt_normalize = 0; }, + 'noconfig' => sub { $opt_config = 0; }, + 'today' => sub { $opt_file = "/var/log/net-acct/net-acct.log"; } +) or $bad_arg = 1; -## Options -for (my $ct = 0; $ct < @ARGV; $ct++) +if ($bad_arg == 1) +{ usage(); } + +my ($mail_msg, $mail_fh); + +# Lit les options du fichier de config +# sauf si --noconfig est utilise +if ($opt_config) +{ read_configfile(); } + +# Begin Mail ? +if ($opt_mail ne "") { - if ($ARGV[$ct] eq '-d' || $ARGV[$ct] eq '--download') { - $download = 1; - } elsif ($ARGV[$ct] eq '-h' || $ARGV[$ct] eq '--host') { - if ($ARGV[$ct+1] =~ /[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/) - { $host = $ARGV[$ct+1]; $ct++; } - else { $host = inet_ntoa((gethostbyname($ARGV[$ct+1]))[4]); $ct++; } - #else { usage(); } # C'est quand meme chiant de pas pouvoir utiliser les hostnames ! Allez, on implémente :) -- Nico - } elsif ($ARGV[$ct] =~ '-n' || $ARGV[$ct] eq '--nombre') { - if ($ARGV[$ct+1]) - { $nombre_line_affiche = $ARGV[$ct+1]; $ct++; } - else { usage(); } - } elsif ($ARGV[$ct] eq '-f' || $ARGV[$ct] eq '--file') { - if ($ARGV[$ct+1]) - { $inputfile = $ARGV[$ct+1]; $ct++; } - else { usage(); } - } elsif ( $ARGV[$ct] =~ '--nodns') { - $dns_resolve = 0; - } elsif ( $ARGV[$ct] =~ '--help') { - usage(); - } + $mail_msg = new Mail::Send; + $mail_fh = $mail_msg->open(); + $mail_msg->to($opt_mail); + $mail_msg->subject("[ANALYSE]"); + close (STDOUT); + open (STDOUT, ">/tmp/analyse_mail"); } -if ($host ne "") { - get_host_info($host); -} else { - show_all($nombre_line_affiche, !$download); +# Main Part +if ($opt_host ne "") +{ get_host_info($opt_host); } +else +{ show_all($opt_number, $opt_upload); } + +# Close Mail +if ($opt_mail ne "") +{ + close (STDOUT); + open (FH, "/tmp/analyse_mail") || die ("argh not possible !\n"); + while (my $line = ) + { print $mail_fh $line; } + close (FH); + $mail_fh->close(); } exit (0);