PHP for dealing with IP Address searching

So, we’ve got a home-grown device/IP/network management system at work. Backend’s Postgres/PHP, front end is horrible and hilariously ugly. It works, mostly. Since I’m the only one with any skills in the space, it falls to me to find ways to Make Things Better.

Today’s fun was making the search box a little less horrible - searching for devices in in a subnet wasn’t easy unless you wanted to find the subnet’s location, then drill down from there.

This is the function which looks at what someone has entered into the box then makes a little SQL snippet. It’ll return False if you’ve entered something it doesn’t know how to deal with (which the display code handles).

This howto helped a lot, well worth checking out if you need info on how to do subnet calculations etc.

`So, we’ve got a home-grown device/IP/network management system at work. Backend’s Postgres/PHP, front end is horrible and hilariously ugly. It works, mostly. Since I’m the only one with any skills in the space, it falls to me to find ways to Make Things Better.

Today’s fun was making the search box a little less horrible - searching for devices in in a subnet wasn’t easy unless you wanted to find the subnet’s location, then drill down from there.

This is the function which looks at what someone has entered into the box then makes a little SQL snippet. It’ll return False if you’ve entered something it doesn’t know how to deal with (which the display code handles).

This howto helped a lot, well worth checking out if you need info on how to do subnet calculations etc.

`

function ipaddr_searchterm( $ipaddr )
    {
    # feed it something like an ip address and you'll get an sql snippet back
    # valid inputs are an IP address, a CIDR chunk or a xxx.xxx. or similar (some octets with a . on the end)

    $justip = '/^[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}$/';
    $isCIDR = '#^[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\/[\d]{1,2}#';

    $ipaddr = trim( rtrim( $ipaddr ) );
    #echo "Testing: '{$ipaddr}'";
    $fullip = preg_match( $justip,$ipaddr );
    $cidr = preg_match( $isCIDR, $ipaddr );

    # entered a single IP address
    if( $fullip )
        {
        #echo "Plain IP address found, zing";
        return " where ipaddr = ".ip2long( $ipaddr );
        }

    # entered a CIDR string
    elseif( $cidr )
        {
        #echo "Is CIDR, argh!";
        $bits = explode( "/", $ipaddr );
        $subnet = $bits[0];
        $bitmask= $bits[1];
        #echo "Subnet: {$subnet}
        Bits: {$bitmask}";
        if( $bitmask > 32 or $bitmask <= 0 )
            {
            #echo "Invalid Bitmask, dying";
            return False;
            }
        else
            {
            #echo "Valid ip/bitmask.";
            $bitlength = 32-$bitmask;
            $numhosts = pow( 2, $bitlength );
            if( $numhosts > 1 )
                {
                #echo "Number of hosts: ".pow( 2, $bitlength )."";
                #echo "Bitlength: {$bitlength}";
                $tophost = ip2long( $subnet ) + pow( 2, $bitlength )-1;
                #echo "Hosts from: {$subnet} to ".long2ip( $tophost )."";
                return " where ipaddr >= ".ip2long( $subnet )." AND ipaddr <= {$tophost} ";
                }
            else
                {
                #echo "Single host: {$subnet}";
                return " where ipaddr = ".ip2long( $subnet );
                }
            }
    }
    elseif( endswith( $ipaddr, "." ) )
        {
        #echo "Ends with a .?";
        preg_match_all( '/[\d]{1,3}\./', $ipaddr, $output );
        $output = $output[0];

        #hacky validation of the match
        if( implode( $output ) == $ipaddr )
            {
            #echo "Subnet size: ".count( $output )."";
            $newip = implode( $output );
            for( $i = 3 - count( $output ); $i--; $i > 0 )
                {
                $newip = $newip."0.";
                }
            $newip = $newip."0";
            #echo "{$newip}";
            $hostcount = pow( 256, 4 - count( $output ) ) - 1;
            #echo "Hosts: {$hostcount}";
            return " where ipaddr >= ".ip2long( $newip )." and ipaddr <= ".(ip2long( $newip ) + $hostcount)." ";
            }
        }
    else
        {
        #echo "Unknown input, ignoring.";
        return False;
        }
    }

 



#coding #php #Programming #Work