PDA

View Full Version : Checking an incoming IP against banned IP classes.


Cjwinnit
10-03-2011, 05:59 PM
As my first post I thought it might be a laff for you guys to look at one of my scripts.

Ever wanted a to see if an IP is within a list of ip's? is 145.78.4.3 in either 145.7.*.* or bla.bla.bla.* ?

First you need the folowing two functions:

####function used in checking for subnets#############
function ipto32bin ( $ipthingee )
{
$ipthingee = explode(".",$ipthingee);

$iinf = 0; do {

$ipthingee[$iinf] = decbin($ipthingee[$iinf]);

$iinf++;} while($iinf<=3);

$ipasabin = sprintf("%08d%08d%08d%08d", $ipthingee[0],$ipthingee[1],$ipthingee[2],$ipthingee[3]);

return $ipasabin;
}
###########################

###########################
function isipinsub ( $ip, $ipsub )
{
$x = strpos($ipsub, "/");

$lengthcomp = substr($ipsub, $x + 1);

$subip = substr($ipsub, 0, $x);

$ip = ipto32bin($ip);

$subip = ipto32bin($subip);

$ip = substr($ip,0,$lengthcomp);

$subip = substr($subip,0,$lengthcomp);

if($ip === $subip) return TRUE;
else return FALSE;
}
########################################################

You now have a function that will return true or false as a boolean. Examples:

isipinsub ( 192.168.0.50, 192.168.0.0/24 ) will return TRUE,

isipinsub ( 73.56.4.5, 10.0.0.0/8 ) will return FALSE.

You can use this if you have a list of collections of IPs you wish to ban, or take your page offline to everyone except a particular subnet.

How I use it:
###maintenance page#########
if($ini_page[kill_page] == "true"){

if($ini_page[kill_override] == "false")
{ require ("pages/maintenance.php"); die; }

if(!isipinsub($_SERVER["REMOTE_ADDR"], $ini_page[kill_override_iprange]) &&
!in_array($_SERVER["REMOTE_ADDR"],$ini_page[kill_override_ip_list]))
{ require ("pages/maintenance.php"); die; }


}
############################
#######checks ban list######

if(($ini_page[kill_page] != "true") && ($ini_page[banned_ipranges][0] != "")){

foreach($ini_page[banned_ipranges] as $val)
{
if(isipinsub ($_SERVER["REMOTE_ADDR"], $val)){ require ("pages/maintenance.php"); die; }

}}

###end maintenance page####


Enjoy!

Cjwinnit
10-20-2011, 05:46 PM
Following another thread ( see here (http://www.codingforums.com/showthread.php?t=241352) ) I wondered if I could edit the function. Well, I have!
It should now be ok using either plain IPs, classes in * form and CIDR-style ranges of IPs.

Examples:
isipinsub(192.168.6.1, 192.168.6.0/8) returns true.
isipinsub(192.168.6.1, 192.168.6.0/16) returns true.
isipinsub(192.168.6.1, 192.168.6.0/24) returns true.
isipinsub(192.168.6.1, 192.168.6.0/32) returns false.
isipinsub(192.168.6.0, 192.168.6.0/32) returns true.

isipinsub(192.168.6.1, 192.168.6.*) returns true.
isipinsub(192.168.6.1, 192.168.*.*) returns true.
isipinsub(192.168.6.1, 192.*.6.*) returns true.
isipinsub(192.168.6.1, *.*.*.*) returns true.
isipinsub(192.168.6.1, *.*.*.2) returns false.

isipinsub(192.168.6.0, 192.168.6.1) returns false.
isipinsub(192.168.6.0, 192.168.6.0) returns true.

First one is functionally the same but has been tidied up a bit.

#---------------------------------#
#------ipto32bin function---------#
#---------------------------------#
#-used in the isipinsub function--#
#--converts an IP into a 32-bit---#
#--------binary string.-----------#
#---------------------------------#

function ipto32bin ( $ipthingee )
{
$ipthingee = explode(".",$ipthingee);
//Change each bit of the IP to it's equivalent binary.
$iinf = 0; do {

$ipthingee[$iinf] = decbin($ipthingee[$iinf]);

$iinf++;} while($iinf<=3);

//Sow the whole thing up.
//MUST be 32 bits long, hence "%08d" four times.
//This pads out the smaller numbers correctly.
$ipthingee = sprintf("%08d%08d%08d%08d", $ipthingee[0],$ipthingee[1],$ipthingee[2],$ipthingee[3]);

//Done!
return $ipthingee;
}
#---ipto32bin function end--------#


Second one is modified heavily.


#---------------------------------#
#------isipinsub function---------#
#---------------------------------#
#--checks whether an IP is in a---#
#--subnet. Can understand single--#
#--IPs, CIDR-style and 'asterisk'-#
#----style entries. Returns as----#
#------either true or false.------#
#----Needs ipto32bin function.----#
#------Cjwinnit@codingforums------#
#---------------------------------#

function isipinsub ( $ip, $ipsub )
{
$x = strpos($ipsub, "/");
$y = strpos($ipsub, "*");

//The next if statement works out
//if it contains (an) asterisk(s) or a slash.
//If it has neither, we treat it as a single IP
//and we go straight to the comparison at the end.

if (!($x === false) || !($y === false))
{
//so it's either CIDR-style or asterisk.
//do different things to each...
if (!($x === false))
{
//it's CIDR-style. Nick the end number.
$lengthcomp = substr($ipsub, $x + 1);
//trim off the end number and slash.
$ipsub = substr($ipsub, 0, $x);
//next two lines trim the binary strings
//to the correct length using $lengthcomp.

$ip = substr(ipto32bin($ip),0,$lengthcomp);
$ipsub = substr(ipto32bin($ipsub),0,$lengthcomp);
//We'll go-compaa-AARE! at the end.

} else {
//Asterisk-style. Bit more complicated...

$asteriskarraysub = explode(".",$ipsub);
$asteriskarray = explode(".",$ip);
//do an element-by-element comparison.
$iinf = 0; do {
if (!(($asteriskarraysub[$iinf] == $asteriskarray[$iinf]) || ($asteriskarraysub[$iinf] == "*"))) { return FALSE; }
$iinf++;

} while($iinf<=3);
//each of the elements in original IP pairs up
//with either it's own number in subip or "*" in subip.
//Therefore it's in the subnet.
return TRUE;
}

}
//It's where you go to,
//Insure your motor....
if($ip === $ipsub) return TRUE;
else return FALSE;
}
#------isipinsub function end-----#


Test script if you need it:

<?php
$ipthing = "192.168.1.201";
$ipsubthing = "*.*.*.201";

if(isipinsub ($ipthing, $ipsubthing)) {echo "It's in the subnet."; } else { echo "Nope."; }
?>