Stupid PHP tricks
Jul. 19th, 2012 04:59 pmSo, I'm trying to write some stuff in PHP, and I've run into a thing I can't seem to figure out how to do. I want to take two IP addresses (in dotted decimal format) and a CIDR mask, and see if IP-1 is contained within IP-2/mask.
I've been poking around to see if this is an obviously solved problem - and I would think it must be, because it's not an unusual problem, but I can't seem to find it. And trying to script this myself is causing me to go cross-eyed trying to figure out how to do binary math without the ability to cast a variable as a binary. (Really, PHP? Really?)
I suppose one solution is to go get a real language, or maybe wait until phpv6. But, still, for something that's allegedly optimized for web-based stuff, I'm really shocked there doesn't seem to be much in the way of built-in IP-wrangling stuff besides, say, "ip2long" which will take a dotted decimal format IPv4 addr and turn it into a long integer.
I've been poking around to see if this is an obviously solved problem - and I would think it must be, because it's not an unusual problem, but I can't seem to find it. And trying to script this myself is causing me to go cross-eyed trying to figure out how to do binary math without the ability to cast a variable as a binary. (Really, PHP? Really?)
I suppose one solution is to go get a real language, or maybe wait until phpv6. But, still, for something that's allegedly optimized for web-based stuff, I'm really shocked there doesn't seem to be much in the way of built-in IP-wrangling stuff besides, say, "ip2long" which will take a dotted decimal format IPv4 addr and turn it into a long integer.
no subject
Date: 2012-07-19 09:06 pm (UTC)no subject
Date: 2012-07-19 09:23 pm (UTC)clearly, your google-fu is superior!
(i kept finding solutions in languages that weren't php, like c#)
no subject
Date: 2012-07-19 09:27 pm (UTC)It's like the seventh hit.
no subject
Date: 2012-07-19 10:30 pm (UTC)Thanks!
no subject
Date: 2012-07-20 12:05 am (UTC)no subject
Date: 2012-07-20 01:31 pm (UTC)no subject
Date: 2012-07-20 01:03 am (UTC)no subject
Date: 2012-07-20 01:30 pm (UTC)thanks!
no subject
Date: 2012-07-20 02:17 am (UTC)TEST_IP4_NETWORK_ADDR < TEST_IP4ADDR < (TEST_IP4_NETWORK_ADDR + (2^(32 - N))
adjust those '<' to '<=' appropriately based on what your broadcast address convention is. If you aren't guaranteed to be handed TEST_IP4_NETWORK_ADDR is a sane way, that is, an integer that has those last (32-N) bits zero, you can stamp those out by subtracting off (TEST_IP4_NETWORK_ADDR mod (2^(32-N))).
no subject
Date: 2012-07-20 01:29 pm (UTC)I was definitely fixated on "it's a 32 bit number, so i need to shift the bits over by $netmask.
thanks!
no subject
Date: 2012-07-20 03:46 am (UTC)http://us.php.net/manual/en/function.unpack.php
but you don't need to convert to binary to do address manipulation, you can use shift operators on integer variables and php will dtrt:
>4;
echo "$a\n$b\n";
?>
65353
4084
i wrote all the functions for ipv4 manipulation back in the dark ages; if you or mikem saved a copy of cardinal, check out the libraries - i named it something obvious like net_ipv4.lib.php (if you don't i can scratch them up from my backups).
my recollection was that some pretty stock use of integer math (floor, div, multiply, and pow(2) ) was all it took.
no subject
Date: 2012-07-20 04:05 am (UTC)i'll try again:
<?php
$a=65353;
$b = $a>>4;
echo "$a\n$b\n";
?>
65353
4084
equivalent to:
<?php
$foo=65353;
echo "$foo\n";
$foo=floor($foo/2);
echo "$foo\n";
$foo=floor($foo/2);
echo "$foo\n";
$foo=floor($foo/2);
echo "$foo\n";
$foo=floor($foo/2);
echo "$foo\n";
?>
65353
32676
16338
8169
4084
no subject
Date: 2012-07-20 04:09 am (UTC)i think they're a little lamer than what i wrote (who's the humble one ??) but php does have native inet_* functions:
http://us.php.net/manual/en/function.inet-ntop.php
http://us.php.net/manual/en/function.inet-pton.php
http://us.php.net/manual/en/function.ip2long.php
http://us.php.net/manual/en/function.long2ip.php
no subject
Date: 2012-07-20 01:31 pm (UTC)i think i have some of the cardinal stuff around. spelunking thru that was going to be another option since i figured it was in there somewhere.
thanks!
how's it going down there?
no subject
Date: 2012-07-20 06:12 pm (UTC)