#!/usr/bin/perl


# Declaracao de bibliotecas (dependencas)
use warnings;
use v5.10; # for say() function
use DBI;

# Funcao para debug, caso precise visualizar mais dados da execucao
# altere o valor de 0 para 1

# Declaracao de variaveis
my $ipinst = "";
my $sqlq = "";
my $dsn = "DBI:mysql:pabxvirtual";
my $username = "asteriskuser";
my $password = '2sf__d09AJDKaef';
my $DEBUG = 1;
my $tinst ="";
my $cinst = "";
my $chain = "";
if($DEBUG == 1){
	say "Whitelist ipv4 with debug level 1";
}

sub test_chain()
	{
	$tinst = "iptables -vL WhiteList";
	$chain = system ($tinst);
#	say $chain;
		if($chain != 256)
			{
				if($DEBUG == 1)
					{
					say "A Chain já existe no firewall..";
					}
			}else {
				$cinst = "iptables -N WhiteList";
				system ($cinst);
					if($DEBUG == 1) 
						{
						say "criada a chain WhiteList...";
						}
			}
	}

test_chain();
my $dbh  = DBI->connect($dsn,$username,$password);

# TODO
# Este script pode ler no banco de dados apenas valores que ready sejam n , desta forma evita fazer o
# loop em milhares de enderecos (feito).

my $sth = $dbh->prepare(" select id, ready, action, ip, ip_type from pabxvirtual_white_lists where ready= ?");
$sth->execute("n");
	

# Iniciando leitura de instrucoes nao executadas

while (my $res = $sth->fetchrow_hashref){

	# Validacao de retorno com IP + Action = add e Ready = N ,feito.
	if (($res->{ip}) && $res->{action} eq "add" && $res->{ready} eq "n" && $res->{ip_type} eq "ipv4"){

		# TODO
		# Verificar se a tabela WhiteList existe antes da execução ou no 
		# inicio do script, caso nao exista informar em mensagem de erro
		# ou proceder com a criacao

		# TODO
		# tratativa de erro pendente, em caso de erro na execucao do iptables
		# nenhuma mensagem esta sendo exibida

        	$iptinst = "iptables -A WhiteList -s $res->{ip} -j ACCEPT";
	       	qx/$iptinst/;

	        $sqlq ="update pabxvirtual_white_lists set ready='y' where id= ?";

		my $stha = $dbh->prepare($sqlq);
		$stha->execute($res->{id});
		$stha->finish();

		if($DEBUG == 1 ){
			say "adicionado ip: $res->{ip}";
		}

	 # Validacao das instrucoes de remocao do ip
	 }elsif ($res->{ip} && $res->{action} eq "rm" && $res->{ready} eq "n" && $res->{ip_type} eq "ipv4"){

	        $sqlq ="delete from pabxvirtual_white_lists where id= ?";
		my $sthd = $dbh->prepare($sqlq);
	        $sthd->execute($res->{id});
		$sthd->finish();
		my $iptinst = "iptables -D WhiteList -s $res->{ip} -j ACCEPT";
	        qx/$iptinst/;
		
		# TODO
		# tratativa de erro pendente, em caso de erro na execucao do iptables
		# nenhuma mensagem esta sendo exibida

		$sqlq ="update pabxvirtual_white_lists set ready='y' where id= ?";
		$sthd->prepare($sqlq);
		$sthd->execute($res->{id});

		# TODO
		# Tratativa de erro no update pendente

		if($DEBUG == 1 && $res->{ip}){
			say "removido ip: $res->{ip}";
		}
         }
}	
# Encerrando conexao com o banco de dados
$sth->finish();
$dbh->disconnect();
