Je dispose d'une table de liste noire MySQL, avec des plages IPv4, IPv6 ou CIDR simples de l'un ou l'autre type stockées dedans.
Ma table ressemble plus ou moins à ceci :
+-----------+-------------+
| Nom | Type |
+-----------+-------------+
| AdresseIp | VARCHAR(46) |
+-----------+-------------+
| Masque | INT(2) |
+-----------+-------------+
Maintenant, j'aimerais vérifier si une adresse IP donnée se trouve dans l'une des plages CIDR enregistrées. J'ai déjà accompli cela après quelques jours de recherche sur de nombreuses pages, et j'ai finalement simplement adapté la solution suivante à MySQL : PHP5 calculate IPv6 range from cidr prefix?
Ainsi, je transforme une adresse IP + masque CIDR en la première et la dernière adresse IP de cette plage, que je convertis ensuite en nombres en utilisant INET6_ATON et que je compare avec l'opérateur BETWEEN.
Mon implémentation :
Obtenir la dernière adresse IP
FONCTION (`Ip` VARCHAR(46), `Masque` INT(2) UNSIGNED) RETOURNE varchar(39)
DEBUT
DECLARE IpNumber VARBINARY(16);
DECLARE Dernier VARCHAR(39) DEFAULT '';
DECLARE FlexBits, Counter, Deci, NewByte INT UNSIGNED;
DECLARE HexIp VARCHAR(32);
SET IpNumber = INET6_ATON(Ip);
SET HexIp = HEX(IpNumber);
SET FlexBits = 128 - Masque;
SET Counter = 32;
TANT QUE (FlexBits > 0) FAIRE
SET Deci = CONV(SUBSTR(HexIp, Counter, 1), 16, 10);
SET NewByte = Deci | (POW(2, LEAST(4, FlexBits)) - 1);
SET Dernier = CONCAT(CONV(NewByte, 10, 16), Dernier);
IF FlexBits >= 4 THEN SET FlexBits = FlexBits - 4;
ELSE SET FlexBits = 0;
END IF;
SET Counter = Counter - 1;
FIN TANT QUE;
SET Dernier = CONCAT(SUBSTR(HexIp, 1, Counter), Dernier);
RETURN INET6_NTOA(UNHEX(Dernier));
FIN
Obtenir la première adresse IP
FONCTION (`Ip` VARCHAR(46), `Masque` INT(2) UNSIGNED, `AvecMasque` BOOLEAN) RETOURNE varchar(39)
DEBUT
DECLARE Premier VARCHAR (42) DEFAULT '';
SET Premier = INET6_NTOA(UNHEX(RPAD(SUBSTR(HEX(INET6_ATON(Ip)), 1, Masque / 4), 32, 0)));
SI (AvecMasque = 1) ALORS
SET Premier = CONCAT(Premier, '/', CAST(Masque AS CHAR));
FIN SI;
RETURN Premier;
FIN
Cela fonctionne bien ! J'ai juste l'idée que cela pourrait être fait de manière beaucoup plus efficace en utilisant des opérations de bits astucieuses. J'ai lu des tonnes de questions sur ce sujet, mais je n'ai pas vraiment trouvé de solution concrète. Toute aide dans la bonne direction serait vraiment appréciée !
REMARQUE : Seulement pour IPv6, j'ai correctement mis en œuvre IPv4.