Aller au contenu

Noter ce sujet :

Recommended Posts

Bonjour

J’ai un tableau PHP avec des plages d’adresses IP et leur CIDR, par exemple :

"….,"78.153.224.0/19","78.155.128.0/19","78.159.0.0/19","78.192.0.0/10","……..


Je souhaite vérifier qu’une adresse Ip, par exemple 78.229.96.137, fait, ou non, partie du tableau.

Naturellement, la difficulté est dans l’interprétation des CIDR pour faire cette validation.

Merci par avance de vos suggestions.

Francois

Modifié par Dan
Merci d'éviter de changer la police, surtout pour nous affubler de "comic sans"... Voir les règles du Hub concernant les enrichissements typographiques !!!

Partager ce message


Lien à poster
Partager sur d’autres sites

Je prie le modérateur de m'excuser de ce manquement aux règles, convenant simplement que je ne la connaissais pas.



Il n'y avait aucune malice ou recherche de fantaisie dans ma démarche.



Francois


Partager ce message


Lien à poster
Partager sur d’autres sites

Ceci devrait donner le résultat que tu cherches wink.gif

    /**     * Check an IP adress against a CIDR     *     * @param string $cidr     * @param string $ip     * @return boolean     */   function _cidrMatch($cidr, $ip)    {        // Get the base and the bits from the CIDR        list($base, $bits) = explode('/', $cidr);        // Now split it up into it's classes        list($a, $b, $c, $d) = explode('.', $base);        // Now do some bit shifting/switching to convert to ints        $i    = ($a << 24) + ($b << 16) + ($c << 8) + $d;        $mask = $bits == 0 ? 0: (~0 << (32 - $bits));        // Here's our lowest int        $low = $i & $mask;        // Here's our highest int        $high = $i | (~$mask & 0xFFFFFFFF);        // Now split the ip we're checking against up into classes        list($a, $b, $c, $d) = explode('.', $ip);        // Now convert the ip we're checking against to an int        $check = ($a << 24) + ($b << 16) + ($c << 8) + $d;        // If the ip is within the range, including highest/lowest values,        // then it's witin the CIDR range        if ($check >= $low && $check <= $high) {            return true;        } else {            return false;        }    }

Partager ce message


Lien à poster
Partager sur d’autres sites

bonjour Dan et merci pour ta réponse.



J'avais bien compris que le sujet n'était pas simple mais, à voir ta réponse, j'en ai bien la confirmation.



Je vais copier ton code, le comprendre et le tester, un chouette travail en perspective.



Merci encore à toi.



Francois


Partager ce message


Lien à poster
Partager sur d’autres sites

bonjour Dan,



Je reprend ton code après une interruption imprévue.



Ma question: sous quel format exact doit être présenté l'argument $cidr ?



J'obtient facilement un bloc de CIDR sous ce format:



5.10.78.240/29
5.10.83.0/25
5.10.85.212/30
27.116.56.0/22
...

dans un fichier plat.



Faut-il que je le transforme en string comme "5.10.78.240/29", "5.10.83.0/25", "5.10.85.212/30", "27.116.56.0/22", ... ? Si Oui, avec un Fread du fichier plat et un Fwrite dans un fichier Php?



Merci par avance de ton aide.



Francois


Modifié par francoisch

Partager ce message


Lien à poster
Partager sur d’autres sites

bonjour

J’ai pris les CDIP de la France et mon adresse IP (Paris) ; le résultat de la recherche devrait être TRUE.

Le début de ma liste de CDIP :

"2.0.0.0/12 ","5.10.82.128/29 ","5.10.94.240/29 ","5.10.128.0/21 ","….
aménagée dans un fichier nommé france.php.

Je lis ce fichier avec ce bout de code qui utilise la fonction indiquée plus haut :

$fichierEntree = "france.php";$adresseIp = "1.2.3.4";            (adresse réelle changée pour ce post)$retour = _cidrMatch($fichierEntree, $adresseIp);   echo " retour".$retour."<br>";if ( $retour == FALSE ) { echo "Retour = False"; }else  { echo "Retour = True"; }
mais la variable $retour est vide.

Merci de vos conseils.

Francois

Partager ce message


Lien à poster
Partager sur d’autres sites

Où as-tu vu que le premier argument de la fonction _cidrMatch() devait être un fichier r_question6161.gif


Remplace-le par une adresse IP avec cidr, comme "1.2.3.4/24" et refais un test !



Il te faut lire le fichier en boucle et appeler la fonction pour chaque IP/CIDR !


Partager ce message


Lien à poster
Partager sur d’autres sites

Avec un fichier IPS.txt qui contient ceci :



27.116.56.0/22
5.10.78.240/29
5.10.83.0/25
5.10.85.212/30

Ce code fonctionne bien et sort de la boucle dès qu'un match est trouvé :



$monip="5.10.83.12";

$fp=fopen("IPS.txt", "r");

while(($ip = fgets($fp)) !== false) {
if(_cidrMatch($ip, $monip)) {
echo "found in : $ip ";
break;
}
}

ou, comme alternative, avec valeur de sortie "0" si l'IP est non trouvée, "1" si l'IP est trouvée. :



$monip="5.10.83.12";

$fp=fopen("IPS.txt", "r");

while(($ip = fgets($fp)) !== false) {
if(_cidrMatch($ip, $monip))
exit(1);
}
exit(0);

Ce n'était pourtant pas compliqué, si ? :whistling:


Partager ce message


Lien à poster
Partager sur d’autres sites

bonjour Dan



J'ai repris ton code et, effectivement, ça fonctionne impeccablement.



Je n'y étais pas arrivé seul.



Merci de ton aide précieuse.



Francois


Partager ce message


Lien à poster
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant

×