#!/usr/bin/perl $|=1; use DBI; use Switch; use FindBin qw($Bin); use POSIX qw/strftime/; our $messaggi = 0; while( $_ = shift @ARGV ) { $messaggi = 1 if /^\-v$/; } open CONFFILE, "< $Bin/traffico.conf" or die ("Manca file di configurazione\n"); while () { if(/^\$fw_name = "(\S+)"/ ) { $fw_name = $1; } if(/^\$db_host = "(\S+)"/ ) { $db_host = $1; } if(/^\$db_user = "(\S+)"/ ) { $db_user = $1; } if(/^\$db_name = "(\S+)"/ ) { $db_name = $1; } if(/^\$db_pass = "(\S+)"/ ) { $db_pass = $1; } } close CONFFILE; my $sys_error = 0; if (!lockpid ("lock")) { print "Prg in esecuzione"; exit 0; } printf "Inizio attivita' %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); my $dbmysql = DBI->connect("DBI:mysql:;host=$db_host", "$db_user", "$db_pass") or die ($DBI::errstr); $sts = $dbmysql->prepare("use $db_name"); $sts->execute (); my $fw_query = "SELECT id, attivo, aggiornamenti, path, errore FROM firewall WHERE nome = '$fw_name'"; my $fw_sts = $dbmysql->prepare($fw_query); $fw_sts->execute (); my $fw_dato = $fw_sts->fetchrow_hashref; my $fw_id = $$fw_dato{'id'}; my $fw_aggiornamenti = $$fw_dato{'aggiornamenti'}; my $fw_attivo = $$fw_dato{'attivo'}; my $fw_path = $$fw_dato{'path'}; my $fw_errore = $$fw_dato{'errore'}; if ($fw_errore == 2) { fw_update ($fw_id, 0, -1, 0, NULL); log_server($fw_id, 0, 0, 'Connessione ripristinata'); } @path_stat = stat ($fw_path); $permessi = sprintf "%04o", $path_stat[2] & 00700; if (!defined ($path_stat[2])) { $sys_error = 1; fw_update ($fw_id, 0, -1, 1, 'Path configurazioni non disponibile'); log_server($fw_id, 0, 2, 'Path configurazioni non disponibile'); } if (($permessi ne '0700') && (!$sys_error)) { $sys_error = 1; fw_update ($fw_id, 0, -1, 1, 'Path configurazioni non scrivibile'); log_server($fw_id, 0, 2, 'Path configurazioni non scrivibile'); } if (!$sys_error) { fw_update ($fw_id, 0, -1, 0, NULL); } if (($fw_aggiornamenti == 1) && $fw_attivo && !$sys_error) { printf "Inizio gestione aggiornamenti %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); fw_update ($fw_id, 0, 2, 0, NULL); log_server($fw_id, 0, 0, 'Rilevati aggiornamenti'); $azioni_query = "SELECT id, tabella, idtabella, stato FROM azioni WHERE fw = $fw_id AND dataexec IS NULL and ignora = 0 AND stato != 5 ORDER BY id"; my $azioni_sts = $dbmysql->prepare($azioni_query); $azioni_sts->execute (); my $file_ok = 1; while ((my $azioni_dato = $azioni_sts->fetchrow_hashref) && $file_ok) { my $azioni_id = $$azioni_dato{'id'}; my $azioni_tabella = $$azioni_dato{'tabella'}; my $azioni_idtabella = $$azioni_dato{'idtabella'}; my $azioni_stato = $$azioni_dato{'stato'}; switch ($azioni_tabella) { case "interfacce" { if ($azioni_stato == 1 || $azioni_stato == 2) { my $interfacce_query = "SELECT device, descrizione, rate, ceil FROM interfacce WHERE id = $azioni_idtabella"; my $interfacce_sts = $dbmysql->prepare($interfacce_query); $interfacce_sts->execute (); my $interfacce_dato = $interfacce_sts->fetchrow_hashref; my $nome_interfaccia = $$interfacce_dato{'device'}; my $nomefile1 = "$fw_path/".$$interfacce_dato{'device'}; my $nomefile2 = "$fw_path/".$$interfacce_dato{'device'}."-2.root"; open (OUTFILE1, ">", $nomefile1); open (OUTFILE2, ">", $nomefile2); print OUTFILE1 "#".$$interfacce_dato{'descrizione'}."\n"; print OUTFILE1 "DEFAULT=1000\n"; print OUTFILE1 "R2Q=10\n"; print OUTFILE2 "#".$$interfacce_dato{'descrizione'}."\n"; print OUTFILE2 "RATE=".$$interfacce_dato{'rate'}."Mbit\n"; print OUTFILE2 "CEIL=".$$interfacce_dato{'ceil'}."Mbit\n"; print OUTFILE2 "BURST=15k\n"; close OUTFILE1; close OUTFILE2; azione_conf ($azioni_id); log_server($fw_id, $azioni_id, 0, "Inserita interfaccia $nome_interfaccia") if ($azioni_stato == 1); log_server($fw_id, $azioni_id, 0, "Modificata interfaccia $nome_interfaccia") if ($azioni_stato == 2); } elsif ($azioni_stato == 3) { my $interfacce_query = "SELECT device FROM interfacce WHERE id = $azioni_idtabella"; my $interfacce_sts = $dbmysql->prepare($interfacce_query); $interfacce_sts->execute (); my $interfacce_dato = $interfacce_sts->fetchrow_hashref; my $nomefile1 = "$fw_path/".$$interfacce_dato{'device'}; my $nomefile2 = "$fw_path/".$$interfacce_dato{'device'}."-2.root"; unlink ($nomefile1); unlink ($nomefile2); azione_conf ($azioni_id); log_server($fw_id, $azioni_id, 0, "Eliminata interfaccia $nome_interfaccia"); } else { fw_update ($fw_id, 0, 0, 1, 'Richiesta azione non prevista'); azione_conf ($azioni_id); log_server($fw_id, $azioni_id, 2, "Richiesta operazione $azioni_stato non esistente su device $nome_interfaccia"); } } case "defrule" { if ($azioni_stato == 1 || $azioni_stato == 2) { my $defrule_query = "SELECT descrizione, priorita, rate, ceil FROM defrule WHERE id = $azioni_idtabella"; my $defrule_sts = $dbmysql->prepare($defrule_query); $defrule_sts->execute (); my $defrule_dato = $defrule_sts->fetchrow_hashref; my $nomeregola = creanome ($azioni_idtabella); my $nomefile = "$fw_path/$nomeregola"; open (OUTFILE, ">", $nomefile); print OUTFILE "#".$$defrule_dato{'descrizione'}."\n"; print OUTFILE "RATE=".$$defrule_dato{'rate'}."Mbit\n"; print OUTFILE "CEIL=".$$defrule_dato{'ceil'}."Mbit\n"; print OUTFILE "BURST=15k\n"; print OUTFILE "LEAF=sfq\n"; my $rule_query = "SELECT ipin, portin, ipout, portout FROM rule WHERE iddefrule = $azioni_idtabella"; my $rule_sts = $dbmysql->prepare($rule_query); $rule_sts->execute (); while (my $rule_dato = $rule_sts->fetchrow_hashref) { my $ipin = $$rule_dato{'ipin'}; my $portin = $$rule_dato{'portin'}; if ($portin == 0) { $portin = ""; } else { $portin = ":$portin"; } my $ipout = $$rule_dato{'ipout'}; my $portout = $$rule_dato{'portout'}; if ($portout == 0) { $portout = ""; } else { $portout = ":$portout"; } print OUTFILE "RULE=$ipin$portin,$ipout$portout\n"; } print OUTFILE "PRIO=".$$defrule_dato{'priorita'}."\n"; close OUTFILE; azione_conf ($azioni_id); log_server($fw_id, $azioni_id, 0, "Inserita regola $nomeregola") if ($azioni_stato == 1); log_server($fw_id, $azioni_id, 0, "Modificata regola $nomeregola") if ($azioni_stato == 2); } elsif ($azioni_stato == 3) { my $nomeregola = creanome ($azioni_idtabella); my $nomefile = "$fw_path/$nomeregola"; unlink ($nomefile); azione_conf ($azioni_id); log_server($fw_id, $azioni_id, 0, "Eliminata regola $nomeregola"); } else { my $nomeregola = creanome ($azioni_idtabella); fw_update ($fw_id, 0, 0, 1, 'Richiesta azione non prevista'); azione_conf ($azioni_id); log_server($fw_id, $azioni_id, 2, "Richiesta operazione $azioni_stato non esistente su regola $nome_regola"); } } case "RESET" { reset_file ($fw_path); azione_conf ($azioni_id); log_server($fw_id, $azioni_id, 0, "Richiesta operazione di RESET"); } case "FINE APPLICA" { $file_ok = 0; azione_conf ($azioni_id); } else { } } } `/etc/init.d/htbinit restart`; fw_update ($fw_id, 1, 0, 0, NULL); printf "Termine gestione aggiornamenti %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); } elsif (($fw_aggiornamenti == 1) && $fw_attivo && $sys_error) { $azioni_query = "SELECT id, tabella FROM azioni WHERE fw = $fw_id AND dataexec IS NULL and ignora = 0 AND stato = 5"; my $azioni_sts = $dbmysql->prepare($azioni_query); $azioni_sts->execute (); my $azioni_ok = 1; while ((my $azioni_dato = $azioni_sts->fetchrow_hashref) && ($azioni_ok)) { my $azioni_id = $$azioni_dato{'id'}; my $azioni_tabella = $$azioni_dato{'tabella'}; my $azioni_risop = 0; switch ($azioni_tabella) { case "CREADIR" { if (mkdir $fw_path, 0755) { fw_update ($fw_id, 1, 0, 0, NULL); azione_conf ($azioni_id); log_server($fw_id, $azioni_id, 0, "Creato path dati $fw_path"); } else { fw_update ($fw_id, 1, 0, 1, $!); azione_conf ($azioni_id); $azioni_ok = 0; log_server($fw_id, $azioni_id, 2, "Non e' stato possibile creare il path dati $fw_path"); } } } } } estraidati (); lockpid ("unlock"); printf "Termine attivita' %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); exit 0; sub azione_conf { my $id = shift; my $azioniup_query = "UPDATE azioni SET dataexec= NOW() WHERE id = $id"; my $azioniup_sts = $dbmysql->prepare($azioniup_query); $azioniup_sts->execute (); } sub fw_update { my $id = shift; my $syn = shift; my $agg = shift; my $err = shift; my $msg = shift; if ($syn) { $syn = ", ultimosync = NOW()"; } else { $syn = ""; } if ($agg == -1) { $agg = ""; } else { $agg = ", aggiornamenti = $agg"; } my $fwup_query = "UPDATE firewall SET ultimoconn = NOW(), errore = $err, msg_err = '$msg' $syn $agg WHERE id = $id"; my $fwup_sts = $dbmysql->prepare($fwup_query); $fwup_sts->execute (); } sub reset_file { my $dir = shift; opendir (DIR, $dir); my @files = grep { /^[^\.]/ } readdir(DIR); closedir DIR; foreach $file (@files) { unlink ("$dir/$file"); } } sub creanome { my $idparent = shift; my $query = "SELECT interfacce.device, defrule.idparent, defrule.priorita FROM defrule JOIN interfacce ON defrule.idinterfacce = interfacce.id WHERE defrule.id = '$idparent'"; my $sts = $dbmysql->prepare($query); $sts->execute (); my $dato = $sts->fetchrow_hashref; if ($$dato{'idparent'} == 0) { $ritorno = $$dato{'device'}."-2:".$$dato{'priorita'}; return $ritorno; } else { $ritorno = creanome($$dato{'idparent'}).":".$$dato{'priorita'}; return $ritorno; } } sub log_server { my $fw = shift; my $idazione = shift; my $stato = shift; my $testo = shift; my $query = "INSERT log_server SET fw = $fw, idazione = $idazione, data= NOW(), stato = $stato, testo = '$testo'"; my $sts = $dbmysql->prepare($query); $sts->execute (); } sub lockpid { my $op = shift; my $pidfile = "/tmp/traffico.pid"; if ($op eq "lock") { if (open PIDFILE, "< $pidfile") { read PIDFILE, $oldpid, 256; my $exists = kill 0, $oldpid; if ( $exists ) { return 0; } else { close PIDFILE; } } else { close PIDFILE; } open PIDFILE, "> $pidfile" || return 0; print PIDFILE $$; close PIDFILE; } elsif ($op eq "unlock") { unlink $pidfile; } return 1; } sub estraidati { my $class; my $classid; my $parent; my $rate; my $ceil; my $crate; my $sent; my $range; printf "Inizio estrazione dati %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); my $query = "SELECT id, device FROM interfacce WHERE attivo = 1 AND stato != 3"; my $sts = $dbmysql->prepare($query); $sts->execute (); while (my $dato = $sts->fetchrow_hashref) { my $device_id = $$dato{'id'}; my $device = $$dato{'device'}; my $outcompleto; my @outriga; $outcompleto = qx/\/usr\/sbin\/tc -s class show dev $device/; @outriga = split /\n/, $outcompleto; for ($i=0;$i< scalar(@outriga);$i++) { my $rigaatt = $outriga[$i]; if($rigaatt =~ /^ lended: / ) { $range="$rate $ceil"; $crate=sprintf "%8.1lf",$crate; $sent=sprintf "%10.0lf",$sent/1024; $$device{$classid}[0]=$crate if (($conta eq 0) || ($crate > $$device{$classid}[0])); if ($conta eq 0) { $$device{$classid}[4]=$crate; $$device{$classid}[5]=$sent; } else { $$device{$classid}[4] += $crate; } $$device{$classid}[6]=$sent; $$device{$classid}[1]=$crate; $$device{$classid}[2]=$ceil; my @pezzi = split ':', $classid; my $classe = $pezzi[1]; my $defrule_id; if ($classe == 2) { $defrule_id = 0; } else { my $pri_query = "SELECT id FROM defrule WHERE idinterfacce = $device_id AND priorita = $classe AND attivo = 1 AND stato != 3 "; my $pri_sts = $dbmysql->prepare($pri_query); $pri_sts->execute (); my $pri_dato = $pri_sts->fetchrow_hashref; $defrule_id = $$pri_dato{'id'}; } my $prec_query = "SELECT ($sent-sent) AS inviati, TIMESTAMPDIFF(SECOND, data, NOW()) AS tempo FROM dati_traffico WHERE id = (SELECT MAX(id) FROM dati_traffico WHERE idfirewall = $fw_id AND idinterfacce = $device_id AND iddefrule = $defrule_id)"; my $prec_sts = $dbmysql->prepare($prec_query); $prec_sts->execute (); my $media; my $tempo; my $inviati; if (my $prec_dato = $prec_sts->fetchrow_hashref) { $tempo = $$prec_dato{'tempo'}; $inviati = $$prec_dato{'inviati'}; $inviati = $sent if ($inviati < 0); if ($tempo > 0) { $media = $inviati/$tempo; } else { $media = 0; } } else { $media = 0; $inviati = 0; } printf "Inizio inserimento dato iddefrule $defrule_id %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); my $ins_query = "INSERT INTO dati_traffico SET idfirewall = $fw_id, idinterfacce = $device_id, iddefrule = $defrule_id, sent = $sent, rate = $crate, data = NOW(), calc = $media, diff = $inviati"; my $ins_sts = $dbmysql->prepare($ins_query); $ins_sts->execute (); printf "Termine inserimento dato iddefrule $defrule_id %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); next; } if($rigaatt =~ /^ Sent (\d+) bytes /) { $sent=$1; next; } if($rigaatt =~ /^ rate (\S+)(bit|bps) /) { # print "BPS rate!\n" if $2 eq "bps"; ($crate=$1); $crate=~s/K/*1024/; $crate=~s/M/*1024*1024/; $crate=eval $crate; next; } if($rigaatt =~ /^class (\S+) (\S+:\S+) (root|parent (\S+:\S+)) .*rate (\S+)bit ceil (\S+)bit/) { $class=$1; $classid=$2; $rate=$5; $ceil=$6; ($parent=$3)=~s/parent //; printf "Inizio elaborazione classe $classid %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); $rate=~s/K/*1024/; $rate=~s/M/*1024*1024/; $rate=eval $rate; $rate/=1024; $ceil=~s/K/*1024/; $ceil=~s/M/*1024*1024/; $ceil=eval $ceil; $ceil/=1024; next; } } printf "Termine estrazione dati %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi); } }