Jump to content


Photo

Validar Ip Dentro Da Faixa De Ip


  • Faça o login para participar
5 replies to this topic

#1 Neo

Neo

    Ativo

  • Usuários
  • 302 posts
  • Sexo:Não informado

Posted 07/08/2008, 17:30

Boa tarde pessoal, to precisando fazer uma validação de ip do seguinte modo:

imaginem um cadastro onde o usuario entra com um ip:

189.12.125.12

Eu preciso validar este ip que o usuario entrou perante a uma base de dados que contém faixas
de ips cadastrados, ou seja, preciso saber se este IP está dentro de uma dessa faixas de ips,
como poderia fazer isso?

Base de dados contendo faixas de ip
Faixa Inicial Faixa Final
1. 189.12.0.0 - 189.13.255.255
2. 189.24.0.0 - 189.25.255.255
3. 189.48.0.0 - 189.49.255.255
4. 189.70.0.0 - 189.70.255.255

#2 boirock

boirock

    Tecnologia para todos (agora hexa campeão)

  • Usuários
  • 1559 posts
  • Sexo:Masculino
  • Localidade:Curitiba - PR
  • Interesses:PostgreSQL - PHP

Posted 07/08/2008, 17:53

Acho que isso pode te ajudar :)
ip2long

PS: se for uma query dá pra usar funções do próprio SGBD (y)

#3 colerus

colerus

    Novato no fórum

  • Usuários
  • 4 posts
  • Sexo:Não informado
  • Localidade:Petrópolis-RJ
  • Interesses:Diversos

Posted 07/08/2008, 18:45

eu uso uma função minha para fazer isso... aí vai:

<?php
function checaIP($qual,$inicio,$final){
	$sub = explode(".",$qual);
	//rotinas para verificar se é um ip válido...
	if(count($sub) != 4){
		return array(false,"IP Inválido");
	}
	for($i = 0; $i < count($sub); $i++){
		if($sub[$i] < 0 || $sub[$i] > 255 || !is_numeric($sub[$i])){
			return array(false,"IP Inválido");
		}
	}
	$ini = explode(".",$inicio);
	//rotinas para verificar se é um ip válido...
	if(count($ini) != 4){
		return array(false,"Faixa inicial inválida");
	}
	for($i = 0; $i < count($ini); $i++){
		if($ini[$i] < 0 || $ini[$i] > 255 || !is_numeric($ini[$i])){
			return array(false,"Faixa inicial inválida");
		}
	}
	$fim = explode(".",$final);
	//rotinas para verificar se é um ip válido...
	if(count($fim) != 4){
		return array(false,"Faixa final inválida");
	}
	for($i = 0; $i < count($fim); $i++){
		if($fim[$i] < 0 || $fim[$i] > 255 || !is_numeric($fim[$i])){
			return array(false,"Faixa inicial inválida");
		}
	}
	// verificar se as faixas estao corretas
	if($ini[0]> $fim[0]){
		return array(false,"Faixa inicial deve ser menor que faixa final");
	}
	if($ini[1]> $fim[1] && $ini[0] == $fim[0]){
		return array(false,"Faixa inicial deve ser menor que faixa final");
	}
	if($ini[2]> $fim[2] && $ini[0] == $fim[0] && $ini[1] == $fim[1]){
		return array(false,"Faixa inicial deve ser menor que faixa final");
	}
	
	if($ini[3]> $fim[3] && $ini[0] == $fim[0] && $ini[1] == $fim[1] && $ini[2] == $fim[2]){
		return array(false,"Faixa inicial deve ser menor que faixa final");
	}
	
	//enfim verifica se o ip passado está dentro desta faixa...
	if($sub[0] < $ini[0] || $sub[0] > $fim[0]){
		return array(false,"IP fora da faixa");
	}
	if($sub[1] < $ini[1] || $sub[1] > $fim[1]){
		if($sub[0] >! $fim[0] || $sub[0] <! $ini[0]){
			return array(false,"IP Fora da Faixa");
		}
	}
	if($sub[2] < $ini[2] || $sub[2] > $fim[2]){
		if($sub[1] >! $fim[1] || $sub[1] <! $ini[1]){
			if($sub[0] >! $fim[0] || $sub[0] <! $ini[0]){
				return array(false,"FaixaIP Fora da Faixa");
			}
		}
	}
	
	if($sub[3] < $ini[3] || $sub[3] > $fim[3]){
		if($sub[2] >! $fim[2] || $sub[2] <! $ini[2]){
			if($sub[1] >! $fim[1] || $sub[1] <! $ini[1]){
				if($sub[0] >! $fim[0] || $sub[0] <! $ini[0]){
					return array(false,"IP Fora da Faixa");
				}
			}
		}
	}
	return array(true);
}

//Exemplo...
$ip = array("192.168.0.1","192.168.1.1","192.168.255.255","192.168.0.0","0.0.0.0","192.168.0.0",
"192.168.0.255","192.255.0.0","255.168.0.1","192.0.0.0");
$inicio = "192.168.0.0";
$fim = "192.168.0.255";

foreach($ip as $pk){
	$teste = checaIp($pk,$inicio,$fim);
	if($teste[0] == false){
		echo("erro: ". $teste[1] ."; IP: $pk; Inicio: $inicio; Fim: $fim<br />");
	} else {
		echo("Certo... IP: $pk; Inicio: $inicio; Fim: $fim <br />");
	}
}
?>

vlw...
http://colerus.net46.net » Ainda em construção...

#4 Paulo Freitas

Paulo Freitas

    ××××××× LRU #456504 ××××××× ××××××× LRM #364686 ×××××××

  • Ex-Admins
  • 5612 posts
  • Sexo:Masculino
  • Localidade:Campinas - SP

Posted 07/08/2008, 18:47

Só atente-se que o tipo integer do PHP é signed. Isto faz com que a função gere valores negativos para determinados endereços. ;)

Mas deixe-me te tacar uma idéia... Ao invés de ter um campo faixa_inicial e faixa_final no banco de dados, porque não usa um campo só usando o padrão CIDR?

Dê uma lida aqui: http://en.wikipedia....-Domain_Routing

Tomando a primeira faixa (189.12.0.0 - 189.13.255.255) como exemplo, ficaria: 189.12.0.0/15

Aí você poderia usar esta função, contida nesta mesma página do manual:

function netMatch($cidr, $ip)
{
	list($net, $mask) = explode ('/', $cidr);

	return (ip2long($ip) & ~((1 << (32 - $mask)) - 1)) == ip2long($net);
}

Para usá-la:

print netMatch('189.12.0.0/15', '189.12.125.12') ? 'dentro da faixa especificada'
												 : 'fora da faixa especificada';
[]’s :DAté mais

#5 colerus

colerus

    Novato no fórum

  • Usuários
  • 4 posts
  • Sexo:Não informado
  • Localidade:Petrópolis-RJ
  • Interesses:Diversos

Posted 07/08/2008, 20:50

Só atente-se que o tipo integer do PHP é signed. Isto faz com que a função gere valores negativos para determinados endereços. ;)

Mas deixe-me te tacar uma idéia... Ao invés de ter um campo faixa_inicial e faixa_final no banco de dados, porque não usa um campo só usando o padrão CIDR?

Dê uma lida aqui: http://en.wikipedia....-Domain_Routing

Tomando a primeira faixa (189.12.0.0 - 189.13.255.255) como exemplo, ficaria: 189.12.0.0/15

Aí você poderia usar esta função, contida nesta mesma página do manual:

function netMatch($cidr, $ip)
{
	list($net, $mask) = explode ('/', $cidr);

	return (ip2long($ip) & ~((1 << (32 - $mask)) - 1)) == ip2long($net);
}

Para usá-la:

print netMatch('189.12.0.0/15', '189.12.125.12') ? 'dentro da faixa especificada'
												 : 'fora da faixa especificada';
[]’s :D



boa... vou dar uma testada e funcionando direito mando meu script embora... :D:D:D vlw
http://colerus.net46.net » Ainda em construção...

#6 Paulo Freitas

Paulo Freitas

    ××××××× LRU #456504 ××××××× ××××××× LRM #364686 ×××××××

  • Ex-Admins
  • 5612 posts
  • Sexo:Masculino
  • Localidade:Campinas - SP

Posted 07/08/2008, 22:45

boa... vou dar uma testada e funcionando direito mando meu script embora... :D:D:D vlw

Bem, eu gerei todos os IP's desta faixa via script e inseri mais alguns outros inválidos num arquivo. Fiz o teste e somente os inválidos retornaram falso. Com isso creio que esteja totalmente funcional. ;-)

A propósito, se você estiver usando MySQL, pode fazer diretamente da consulta:

SELECT INET_ATON(ip) & ~((1 << (32 - SUBSTRING_INDEX(cidr, '/', -1))) - 1) = INET_ATON(SUBSTRING_INDEX(cidr, '/', 1))
A consulta retorna 1 quando verdadeiro e 0 quando falso.

[]’s :DAté mais




1 user(s) are reading this topic

0 membro(s), 1 visitante(s) e 0 membros anônimo(s)

IPB Skin By Virteq